diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-03-23 21:06:47 +0200 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-03-23 21:06:47 +0200 |
commit | 42e4ae042a4c86e58bcb8b6d2d59ba4a988285b4 (patch) | |
tree | a7f25b1d335a834a7c3ae104cee913ef3a4dd4fb /src/gui | |
parent | 4ee4fc18b4067b90efa46ca9baba74f53b54d9ec (diff) | |
parent | 168ff3419f256fdb35b586275d293fc0cd773fe1 (diff) | |
download | qtbase-42e4ae042a4c86e58bcb8b6d2d59ba4a988285b4.tar.gz |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.9' into tqtc/lts-5.15-opensourcev5.15.9-lts-lgpl5.15
Change-Id: Iaff6b55275e50d19973e1020853d8622587069f9
Diffstat (limited to 'src/gui')
25 files changed, 164 insertions, 105 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index d705bfccb5..d0d46942fb 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -162,7 +162,6 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core"); \value hasPopup The object opens a popup. \value hotTracked The object's appearance is sensitive to the mouse cursor position. \value invalid The object is no longer valid (because it has been deleted). - \value invalidEntry Input validation current input invalid. \value invisible The object is not visible to the user. \value linked The object is linked to another object, e.g. a hyperlink. \value marqueed The object displays scrolling contents, e.g. a log view. diff --git a/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp b/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp index 6527021dd6..5cb100c711 100644 --- a/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp +++ b/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp @@ -66,7 +66,7 @@ mailto:user@foo.com?subject=Test&body=Just a test //! [1] //! [2] -QDesktopServices::openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop", QUrl::TolerantMode)); +QDesktopServices::openUrl(QUrl("file:///C:/Program Files", QUrl::TolerantMode)); //! [2] //! [3] diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index d6ccaff8ed..455088241c 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -251,7 +251,8 @@ void QCursor::setPos(QScreen *screen, int x, int y) { if (screen) { if (QPlatformCursor *cursor = screen->handle()->cursor()) { - const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen); + const QPoint pos(x, y); + const QPoint devicePos = QHighDpi::toNativePixels(pos, screen->virtualSiblingAt(pos)); // Need to check, since some X servers generate null mouse move // events, causing looping in applications which call setPos() on // every mouse move event. diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 87643a3a39..b39b3b4e5e 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -61,7 +61,7 @@ #include <QtCore/private/qlocking_p.h> #include <QtCore/qdir.h> #include <QtCore/qlibraryinfo.h> -#include <QtCore/qnumeric.h> +#include <QtCore/private/qnumeric_p.h> #include <QtDebug> #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" @@ -140,7 +140,7 @@ Q_GUI_EXPORT bool qt_is_gui_used = true; Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton; Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier; -QPointF QGuiApplicationPrivate::lastCursorPosition(qInf(), qInf()); +QPointF QGuiApplicationPrivate::lastCursorPosition(qt_inf(), qt_inf()); QWindow *QGuiApplicationPrivate::currentMouseWindow = nullptr; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index c1c79a74ce..639817257e 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -458,7 +458,7 @@ void QWindowPrivate::updateSiblingPosition(SiblingPosition position) siblings.move(currentPosition, targetPosition); } -inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const +bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const { Q_Q(const QWindow); const QScreen *oldScreen = q->screen(); @@ -466,7 +466,7 @@ inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const && !(oldScreen && oldScreen->virtualSiblings().contains(newScreen)); } -inline void QWindowPrivate::disconnectFromScreen() +void QWindowPrivate::disconnectFromScreen() { if (topLevelScreen) topLevelScreen = nullptr; diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index 3a2393ea58..9dee796eab 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -157,8 +157,6 @@ typedef char GLchar; # endif #endif -QT_BEGIN_NAMESPACE - // When all else fails we provide sensible fallbacks - this is needed to // allow compilation on OS X 10.6 @@ -287,6 +285,7 @@ typedef GLintptr GLvdpauSurfaceNV; // End of block copied from glext.h #endif +QT_BEGIN_NAMESPACE // Types that aren't defined in all system's gl.h files. typedef ptrdiff_t qopengl_GLintptr; diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 2147d9d61d..703c492a6b 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -320,32 +320,34 @@ bool QBackingStore::hasStaticContents() const void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset) { // make sure we don't detach - uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits()); + uchar *mem = const_cast<uchar*>(img.constBits()); int lineskip = img.bytesPerLine(); int depth = img.depth() >> 3; const QRect imageRect(0, 0, img.width(), img.height()); - const QRect r = rect & imageRect & imageRect.translated(-offset); - const QPoint p = rect.topLeft() + offset; - - if (r.isEmpty()) + const QRect sourceRect = rect.intersected(imageRect).intersected(imageRect.translated(-offset)); + if (sourceRect.isEmpty()) return; + const QRect destRect = sourceRect.translated(offset); + Q_ASSERT_X(imageRect.contains(destRect), "qt_scrollRectInImage", + "The sourceRect should already account for clipping, both pre and post scroll"); + const uchar *src; uchar *dest; - if (r.top() < p.y()) { - src = mem + r.bottom() * lineskip + r.left() * depth; - dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth; + if (sourceRect.top() < destRect.top()) { + src = mem + sourceRect.bottom() * lineskip + sourceRect.left() * depth; + dest = mem + (destRect.top() + sourceRect.height() - 1) * lineskip + destRect.left() * depth; lineskip = -lineskip; } else { - src = mem + r.top() * lineskip + r.left() * depth; - dest = mem + p.y() * lineskip + p.x() * depth; + src = mem + sourceRect.top() * lineskip + sourceRect.left() * depth; + dest = mem + destRect.top() * lineskip + destRect.left() * depth; } - const int w = r.width(); - int h = r.height(); + const int w = sourceRect.width(); + int h = sourceRect.height(); const int bytes = w * depth; // overlapping segments? diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h index 080da98ec4..6997d62b3c 100644 --- a/src/gui/painting/qblendfunctions_p.h +++ b/src/gui/painting/qblendfunctions_p.h @@ -246,25 +246,32 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, int dudx, int dvdx, int dudy, int dvdy, int u0, int v0, Blender blender) { - int fromY = qMax(qRound(topY), clip.top()); - int toY = qMin(qRound(bottomY), clip.top() + clip.height()); + qint64 fromY = qMax(qRound(topY), clip.top()); + qint64 toY = qMin(qRound(bottomY), clip.top() + clip.height()); if (fromY >= toY) return; qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y); qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y); - int dx_l = int(leftSlope * 0x10000); - int dx_r = int(rightSlope * 0x10000); - int x_l = int((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000); - int x_r = int((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000); - - int fromX, toX, x1, x2, u, v, i, ii; + qint64 dx_l = qint64(leftSlope * 0x10000); + qint64 dx_r = qint64(rightSlope * 0x10000); + qint64 x_l = qint64((topLeft.x + (qreal(0.5) + fromY - topLeft.y) * leftSlope + qreal(0.5)) * 0x10000); + qint64 x_r = qint64((topRight.x + (qreal(0.5) + fromY - topRight.y) * rightSlope + qreal(0.5)) * 0x10000); + + qint64 sourceRectTop = qint64(sourceRect.top()); + qint64 sourceRectLeft = qint64(sourceRect.left()); + qint64 sourceRectWidth = qint64(sourceRect.width()); + qint64 sourceRectHeight = qint64(sourceRect.height()); + qint64 clipLeft = qint64(clip.left()); + qint64 clipWidth = qint64(clip.width()); + + qint64 fromX, toX, x1, x2, u, v, i, ii; DestT *line; - for (int y = fromY; y < toY; ++y) { + for (qint64 y = fromY; y < toY; ++y) { line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl); - fromX = qMax(x_l >> 16, clip.left()); - toX = qMin(x_r >> 16, clip.left() + clip.width()); + fromX = qMax(x_l >> 16, clipLeft); + toX = qMin(x_r >> 16, clipLeft + clipWidth); if (fromX < toX) { // Because of rounding, we can get source coordinates outside the source image. // Clamp these coordinates to the source rect to avoid segmentation fault and @@ -275,10 +282,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, u = x1 * dudx + y * dudy + u0; v = x1 * dvdx + y * dvdy + v0; for (; x1 < toX; ++x1) { - int uu = u >> 16; - int vv = v >> 16; - if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() - && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { + qint64 uu = u >> 16; + qint64 vv = v >> 16; + if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth + && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) { break; } u += dudx; @@ -290,10 +297,10 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, u = (x2 - 1) * dudx + y * dudy + u0; v = (x2 - 1) * dvdx + y * dvdy + v0; for (; x2 > x1; --x2) { - int uu = u >> 16; - int vv = v >> 16; - if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width() - && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) { + qint64 uu = u >> 16; + qint64 vv = v >> 16; + if (uu >= sourceRectLeft && uu < sourceRectLeft + sourceRectWidth + && vv >= sourceRectTop && vv < sourceRectTop + sourceRectHeight) { break; } u -= dudx; @@ -308,8 +315,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, // Beginning of the scan line, with per-pixel checks. i = x1 - fromX; while (i) { - int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); - int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); + qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1); + qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1); blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]); u += dudx; v += dvdx; @@ -348,8 +355,8 @@ void qt_transform_image_rasterize(DestT *destPixels, int dbpl, // End of the scan line, with per-pixel checks. i = toX - x2; while (i) { - int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1); - int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1); + qint64 uu = qBound(sourceRectLeft, u >> 16, sourceRectLeft + sourceRectWidth - 1); + qint64 vv = qBound(sourceRectTop, v >> 16, sourceRectTop + sourceRectHeight - 1); blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]); u += dudx; v += dvdx; diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp index ced213e36d..aa3f148934 100644 --- a/src/gui/painting/qcompositionfunctions.cpp +++ b/src/gui/painting/qcompositionfunctions.cpp @@ -1045,12 +1045,12 @@ private: static inline int mix_alpha(int da, int sa) { - return 255 - ((255 - sa) * (255 - da) >> 8); + return 255 - qt_div_255((255 - sa) * (255 - da)); } static inline uint mix_alpha_rgb64(uint da, uint sa) { - return 65535 - ((65535 - sa) * (65535 - da) >> 16); + return 65535U - qt_div_65535((65535U - sa) * (65535U - da)); } /* @@ -1337,7 +1337,7 @@ static inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint int da = qAlpha(d); int sa = qAlpha(s); -#define OP(a, b) 255 - (((255-a) * (255-b)) >> 8) +#define OP(a, b) 255 - qt_div_255((255-a) * (255-b)) int r = OP( qRed(d), qRed(s)); int b = OP( qBlue(d), qBlue(s)); int g = OP(qGreen(d), qGreen(s)); @@ -1367,7 +1367,7 @@ static inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QR uint da = d.alpha(); uint sa = s.alpha(); -#define OP(a, b) 65535 - (((65535-a) * (65535-b)) >> 16) +#define OP(a, b) 65535U - qt_div_65535((65535U-a) * (65535U-b)) uint r = OP( d.red(), s.red()); uint b = OP( d.blue(), s.blue()); uint g = OP(d.green(), s.green()); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 283923de52..38bad9a6b0 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -560,31 +560,6 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix) QRasterPaintEngineState *s = state(); // FALCON: get rid of this line, see drawImage call below. s->matrix = matrix; - QTransform::TransformationType txop = s->matrix.type(); - - switch (txop) { - - case QTransform::TxNone: - s->flags.int_xform = true; - break; - - case QTransform::TxTranslate: - s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx() - && qreal(int(s->matrix.dy())) == s->matrix.dy(); - break; - - case QTransform::TxScale: - s->flags.int_xform = qreal(int(s->matrix.dx())) == s->matrix.dx() - && qreal(int(s->matrix.dy())) == s->matrix.dy() - && qreal(int(s->matrix.m11())) == s->matrix.m11() - && qreal(int(s->matrix.m22())) == s->matrix.m22(); - break; - - default: // shear / perspective... - s->flags.int_xform = false; - break; - } - s->flags.tx_noshear = qt_scaleForTransform(s->matrix, &s->txscale); ensureOutlineMapper(); @@ -617,7 +592,6 @@ QRasterPaintEngineState::QRasterPaintEngineState() flags.bilinear = false; flags.legacy_rounding = false; flags.fast_text = true; - flags.int_xform = true; flags.tx_noshear = true; flags.fast_images = true; @@ -1793,7 +1767,7 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) QRectF cpRect = path.controlPointRect(); const QRectF pathDeviceRect = s->matrix.mapRect(cpRect); // Skip paths that by conservative estimates are completely outside the paint device. - if (!pathDeviceRect.intersects(QRectF(d->deviceRect))) + if (!pathDeviceRect.intersects(QRectF(d->deviceRect)) || !pathDeviceRect.isValid()) return; ProcessSpans blend = d->getBrushFunc(pathDeviceRect, &s->brushData); @@ -3095,10 +3069,10 @@ QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect, static QPair<int, int> visibleGlyphRange(const QRectF &clip, QFontEngine *fontEngine, glyph_t *glyphs, QFixedPoint *positions, int numGlyphs) { - QFixed clipLeft = QFixed::fromReal(clip.left()); - QFixed clipRight = QFixed::fromReal(clip.right()); - QFixed clipTop = QFixed::fromReal(clip.top()); - QFixed clipBottom = QFixed::fromReal(clip.bottom()); + QFixed clipLeft = QFixed::fromReal(clip.left() - 1); + QFixed clipRight = QFixed::fromReal(clip.right() + 1); + QFixed clipTop = QFixed::fromReal(clip.top() - 1); + QFixed clipBottom = QFixed::fromReal(clip.bottom() + 1); int first = 0; while (first < numGlyphs) { @@ -3585,7 +3559,7 @@ QRasterPaintEngine::ClipType QRasterPaintEngine::clipType() const \internal Returns the bounding rect of the currently set clip. */ -QRect QRasterPaintEngine::clipBoundingRect() const +QRectF QRasterPaintEngine::clipBoundingRect() const { Q_D(const QRasterPaintEngine); @@ -3597,7 +3571,7 @@ QRect QRasterPaintEngine::clipBoundingRect() const if (clip->hasRectClip) return clip->clipRect; - return QRect(clip->xmin, clip->ymin, clip->xmax - clip->xmin, clip->ymax - clip->ymin); + return QRectF(clip->xmin, clip->ymin, clip->xmax - clip->xmin, clip->ymax - clip->ymin); } void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data) diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 089aadc3f7..7b15292ebb 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -111,7 +111,6 @@ public: uint bilinear : 1; uint legacy_rounding : 1; uint fast_text : 1; - uint int_xform : 1; uint tx_noshear : 1; uint fast_images : 1; }; @@ -206,7 +205,7 @@ public: ComplexClip }; ClipType clipType() const; - QRect clipBoundingRect() const; + QRectF clipBoundingRect() const; #ifdef Q_OS_WIN void setDC(HDC hdc); diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h index 9444a87b71..18f64c5e8c 100644 --- a/src/gui/painting/qpathclipper_p.h +++ b/src/gui/painting/qpathclipper_p.h @@ -156,7 +156,7 @@ public: int vertex(Direction direction) const; private: - int m_next[2][2]; + int m_next[2][2] = { { -1, -1 }, { -1, -1 } }; }; class QPathSegments @@ -296,10 +296,6 @@ inline QPathEdge::QPathEdge(int a, int b) , angle(0) , invAngle(0) { - m_next[0][0] = -1; - m_next[1][0] = -1; - m_next[0][0] = -1; - m_next[1][0] = -1; } inline int QPathEdge::next(Traversal traversal, Direction direction) const diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index cb5d395e80..3b6357a893 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -1182,6 +1182,7 @@ void QDashStroker::processCurrentSubpath() // Check if the entire line should be clipped away or simplified bool clipIt = clipping && !lineIntersectsRect(prev, e, clip_tl, clip_br); bool skipDashing = elen * invSumLength > repetitionLimit(); + int maxDashes = dashCount; if (skipDashing || clipIt) { // Cut away full dash sequences. elen -= std::floor(elen * invSumLength) * sumLength; @@ -1196,7 +1197,7 @@ void QDashStroker::processCurrentSubpath() pos = estop; // move pos to next path element done = true; } else { // Dash is on this line - pos = dpos + estart; + pos = --maxDashes > 0 ? dpos + estart : estop; done = pos >= estop; if (++idash >= dashCount) idash = 0; diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 65f0a2262b..ac6c43693b 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -131,7 +131,7 @@ QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *import dev = reinterpret_cast<ID3D11Device *>(importDevice->dev); if (dev) { ID3D11DeviceContext *ctx = reinterpret_cast<ID3D11DeviceContext *>(importDevice->context); - if (SUCCEEDED(ctx->QueryInterface(IID_ID3D11DeviceContext1, reinterpret_cast<void **>(&context)))) { + if (SUCCEEDED(ctx->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void **>(&context)))) { // get rid of the ref added by QueryInterface ctx->Release(); } else { @@ -171,7 +171,7 @@ static IDXGIFactory1 *createDXGIFactory2() using PtrCreateDXGIFactory2 = HRESULT (WINAPI *)(UINT, REFIID, void **); QSystemLibrary dxgilib(QStringLiteral("dxgi")); if (auto createDXGIFactory2 = reinterpret_cast<PtrCreateDXGIFactory2>(dxgilib.resolve("CreateDXGIFactory2"))) { - const HRESULT hr = createDXGIFactory2(0, IID_IDXGIFactory2, reinterpret_cast<void **>(&result)); + const HRESULT hr = createDXGIFactory2(0, __uuidof(IDXGIFactory2), reinterpret_cast<void **>(&result)); if (FAILED(hr)) { qWarning("CreateDXGIFactory2() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr))); result = nullptr; @@ -186,7 +186,7 @@ static IDXGIFactory1 *createDXGIFactory2() static IDXGIFactory1 *createDXGIFactory1() { IDXGIFactory1 *result = nullptr; - const HRESULT hr = CreateDXGIFactory1(IID_IDXGIFactory1, reinterpret_cast<void **>(&result)); + const HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void **>(&result)); if (FAILED(hr)) { qWarning("CreateDXGIFactory1() failed to create DXGI factory: %s", qPrintable(comErrorMessage(hr))); result = nullptr; @@ -269,7 +269,7 @@ bool QRhiD3D11::create(QRhi::Flags flags) qWarning("Failed to create D3D11 device and context: %s", qPrintable(comErrorMessage(hr))); return false; } - if (SUCCEEDED(ctx->QueryInterface(IID_ID3D11DeviceContext1, reinterpret_cast<void **>(&context)))) { + if (SUCCEEDED(ctx->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void **>(&context)))) { ctx->Release(); } else { qWarning("ID3D11DeviceContext1 not supported"); @@ -280,7 +280,7 @@ bool QRhiD3D11::create(QRhi::Flags flags) featureLevel = dev->GetFeatureLevel(); } - if (FAILED(context->QueryInterface(IID_ID3DUserDefinedAnnotation, reinterpret_cast<void **>(&annotations)))) + if (FAILED(context->QueryInterface(__uuidof(ID3DUserDefinedAnnotation), reinterpret_cast<void **>(&annotations)))) annotations = nullptr; deviceLost = false; @@ -336,7 +336,7 @@ void QRhiD3D11::reportLiveObjects(ID3D11Device *device) { // this works only when params.enableDebugLayer was true ID3D11Debug *debug; - if (SUCCEEDED(device->QueryInterface(IID_ID3D11Debug, reinterpret_cast<void **>(&debug)))) { + if (SUCCEEDED(device->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void **>(&debug)))) { debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); debug->Release(); } @@ -4197,7 +4197,7 @@ bool QD3D11SwapChain::buildOrResize() // swapchain." // So just query index 0 once (per resize) and be done with it. - HRESULT hr = swapChain->GetBuffer(0, IID_ID3D11Texture2D, reinterpret_cast<void **>(&backBufferTex)); + HRESULT hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&backBufferTex)); if (FAILED(hr)) { qWarning("Failed to query swapchain backbuffer: %s", qPrintable(comErrorMessage(hr))); return false; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index f3e6ea2100..72267e9380 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2123,7 +2123,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p { Q_Q(const QTextDocumentLayout); const QTextBlockFormat blockFormat = bl.blockFormat(); - const QTextCharFormat charFormat = QTextCursor(bl).charFormat(); + const QTextCharFormat charFormat = bl.charFormat(); QFont font(charFormat.font()); if (q->paintDevice()) font = QFont(font, q->paintDevice()); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index ce4abac472..6336fadf74 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1565,6 +1565,12 @@ void QTextEngine::shapeText(int item) const // Overwrite with 0 token to indicate failure QGlyphLayout g = availableGlyphs(&si); g.glyphs[0] = 0; + g.attributes[0].clusterStart = true; + + ushort *log_clusters = logClusters(&si); + for (int i = 0; i < itemLength; ++i) + log_clusters[i] = 0; + return; } diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 124c530cb5..5458e646c5 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -784,8 +784,8 @@ void QTextHtmlParser::parseCloseTag() void QTextHtmlParser::parseExclamationTag() { ++pos; - if (hasPrefix(QLatin1Char('-'),1) && hasPrefix(QLatin1Char('-'),2)) { - pos += 3; + if (hasPrefix(QLatin1Char('-')) && hasPrefix(QLatin1Char('-'), 1)) { + pos += 2; // eat comments int end = txt.indexOf(QLatin1String("-->"), pos); pos = (end >= 0 ? end + 3 : len); @@ -880,7 +880,7 @@ QString QTextHtmlParser::parseWord() while (pos < len) { QChar c = txt.at(pos++); if (c == QLatin1Char('>') - || (c == QLatin1Char('/') && hasPrefix(QLatin1Char('>'), 1)) + || (c == QLatin1Char('/') && hasPrefix(QLatin1Char('>'))) || c == QLatin1Char('<') || c == QLatin1Char('=') || c.isSpace()) { diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index 31f558709f..e5622afe9d 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -323,7 +323,9 @@ protected: void applyAttributes(const QStringList &attributes); void eatSpace(); inline bool hasPrefix(QChar c, int lookahead = 0) const - {return pos + lookahead < len && txt.at(pos) == c; } + { + return pos + lookahead < len && txt.at(pos + lookahead) == c; + } int margin(int i, int mar) const; bool nodeIsChildOf(int i, QTextHTMLElements id) const; diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp index e0d16d2d2a..cff4f12b5d 100644 --- a/src/gui/text/qtextmarkdownimporter.cpp +++ b/src/gui/text/qtextmarkdownimporter.cpp @@ -418,6 +418,7 @@ int QTextMarkdownImporter::cbEnterSpan(int spanType, void *det) } case MD_SPAN_CODE: charFmt.setFont(m_monoFont); + charFmt.setFontFixedPitch(true); break; case MD_SPAN_DEL: charFmt.setFontStrikeOut(true); diff --git a/src/gui/text/qtextmarkdownwriter.cpp b/src/gui/text/qtextmarkdownwriter.cpp index ae63fcb4dd..3b4d794c1a 100644 --- a/src/gui/text/qtextmarkdownwriter.cpp +++ b/src/gui/text/qtextmarkdownwriter.cpp @@ -531,7 +531,7 @@ int QTextMarkdownWriter::writeBlock(const QTextBlock &block, bool wrap, bool ign col += s.length(); } else { QFontInfo fontInfo(fmt.font()); - bool monoFrag = fontInfo.fixedPitch(); + bool monoFrag = fontInfo.fixedPitch() || fmt.fontFixedPitch(); QString markers; if (!ignoreFormat) { if (monoFrag != mono && !m_indentedCodeBlock && !m_fencedCodeBlock) { diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 80c0f122e8..feab5b85b9 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -1024,13 +1024,33 @@ bool QZipReader::extractAll(const QString &destinationDir) const // create directories first const QVector<FileInfo> allFiles = fileInfoList(); + bool foundDirs = false; + bool hasDirs = false; for (const FileInfo &fi : allFiles) { const QString absPath = destinationDir + QDir::separator() + fi.filePath; if (fi.isDir) { + foundDirs = true; if (!baseDir.mkpath(fi.filePath)) return false; if (!QFile::setPermissions(absPath, fi.permissions)) return false; + } else if (!hasDirs && fi.filePath.contains(u"/")) { + // filePath does not have leading or trailing '/', so if we find + // one, than the file path contains directories. + hasDirs = true; + } + } + + // Some zip archives can be broken in the sense that they do not report + // separate entries for directories, only for files. In this case we + // need to recreate directory structure based on the file paths. + if (hasDirs && !foundDirs) { + for (const FileInfo &fi : allFiles) { + const auto dirPath = fi.filePath.left(fi.filePath.lastIndexOf(u"/")); + if (!baseDir.mkpath(dirPath)) + return false; + // We will leave the directory permissions default in this case, + // because setting dir permissions based on file is incorrect } } diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index fbb63a9408..4446b4297a 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -54,6 +54,8 @@ #include <qpa/qplatformintegration.h> #include <qdir.h> +#include <QtCore/private/qlocking_p.h> + QT_BEGIN_NAMESPACE class QOpenUrlHandlerRegistry : public QObject @@ -72,24 +74,33 @@ public: typedef QHash<QString, Handler> HandlerHash; HandlerHash handlers; +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) public Q_SLOTS: void handlerDestroyed(QObject *handler); +#endif }; Q_GLOBAL_STATIC(QOpenUrlHandlerRegistry, handlerRegistry) +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler) { + const auto lock = qt_scoped_lock(mutex); HandlerHash::Iterator it = handlers.begin(); while (it != handlers.end()) { if (it->receiver == handler) { it = handlers.erase(it); + qWarning("Please call QDesktopServices::unsetUrlHandler() before destroying a " + "registered URL handler object.\n" + "Support for destroying a registered URL handler object is deprecated, " + "and will be removed in Qt 6.6."); } else { ++it; } } } +#endif /*! \class QDesktopServices @@ -279,6 +290,10 @@ bool QDesktopServices::openUrl(const QUrl &url) Note that the handler will always be called from within the same thread that calls QDesktopServices::openUrl(). + You must call unsetUrlHandler() before destroying the handler object, so + the destruction of the handler object does not overlap with concurrent + invocations of openUrl() using it. + \sa openUrl(), unsetUrlHandler() */ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, const char *method) @@ -293,13 +308,20 @@ void QDesktopServices::setUrlHandler(const QString &scheme, QObject *receiver, c h.receiver = receiver; h.name = method; registry->handlers.insert(scheme.toLower(), h); +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) QObject::connect(receiver, SIGNAL(destroyed(QObject*)), - registry, SLOT(handlerDestroyed(QObject*))); + registry, SLOT(handlerDestroyed(QObject*)), + Qt::DirectConnection); +#endif } /*! Removes a previously set URL handler for the specified \a scheme. + Call this function before the handler object that was registered for \a scheme + is destroyed, to prevent concurrent openUrl() calls from continuing to call + the destroyed handler object. + \sa setUrlHandler() */ void QDesktopServices::unsetUrlHandler(const QString &scheme) diff --git a/src/gui/util/qpkmhandler.cpp b/src/gui/util/qpkmhandler.cpp index e0c3b75efe..3414f9d8ba 100644 --- a/src/gui/util/qpkmhandler.cpp +++ b/src/gui/util/qpkmhandler.cpp @@ -57,7 +57,7 @@ struct PkmType quint32 bytesPerBlock; }; -static PkmType typeMap[5] = { +static constexpr PkmType typeMap[5] = { { 0x8D64, 8 }, // GL_ETC1_RGB8_OES { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2 { 0, 0 }, // unused (obsolete) diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp index 555dee3a9c..19a88074af 100644 --- a/src/gui/vulkan/qvulkaninstance.cpp +++ b/src/gui/vulkan/qvulkaninstance.cpp @@ -531,6 +531,13 @@ void QVulkanInstance::setExtensions(const QByteArrayList &extensions) \note This function can only be called before create() and has no effect if called afterwards. + + \note Be aware that Vulkan 1.1 changes the behavior with regards to the + Vulkan API version field. In Vulkan 1.0 specifying an unsupported \a + vulkanVersion led to failing create() with \c VK_ERROR_INCOMPATIBLE_DRIVER, + as was mandated by the specification. Starting with Vulkan 1.1, the + specification disallows this, the driver must accept any version without + failing the instance creation. */ void QVulkanInstance::setApiVersion(const QVersionNumber &vulkanVersion) { diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index cee1f2540f..14944d47f8 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -195,6 +195,23 @@ Q_LOGGING_CATEGORY(lcGuiVk, "qt.vulkan") \note QVulkanWindow does not expose device layers since this functionality has been deprecated since version 1.0.13 of the Vulkan API. + \section1 Layers, device features, and extensions + + To enable instance layers, call QVulkanInstance::setLayers() before creating + the QVulkanInstance. To query what instance layer are available, call + QVulkanInstance::supportedLayers(). + + To enable device extensions, call setDeviceExtensions() early on when setting + up the QVulkanWindow. To query what device extensions are available, call + supportedDeviceExtensions(). + + Specifying an unsupported layer or extension is handled gracefully: this will + not fail instance or device creation, but the layer or extension request is + rather ignored. + + When it comes to device features, QVulkanWindow enables all Vulkan 1.0 + features that are reported as supported from vkGetPhysicalDeviceFeatures(). + \sa QVulkanInstance, QWindow */ @@ -712,6 +729,12 @@ void QVulkanWindowPrivate::init() devInfo.enabledExtensionCount = devExts.count(); devInfo.ppEnabledExtensionNames = devExts.constData(); + // Enable all 1.0 features. + VkPhysicalDeviceFeatures features; + memset(&features, 0, sizeof(features)); + f->vkGetPhysicalDeviceFeatures(physDev, &features); + devInfo.pEnabledFeatures = &features; + // Device layers are not supported by QVulkanWindow since that's an already deprecated // API. However, have a workaround for systems with older API and layers (f.ex. L4T // 24.2 for the Jetson TX1 provides API 1.0.13 and crashes when the validation layer @@ -2020,7 +2043,7 @@ void QVulkanWindowPrivate::endFrame() // order to circumvent driver frame callbacks inst->presentAboutToBeQueued(q); - err = vkQueuePresentKHR(gfxQueue, &presInfo); + err = vkQueuePresentKHR(presQueue, &presInfo); if (err != VK_SUCCESS) { if (err == VK_ERROR_OUT_OF_DATE_KHR) { recreateSwapChain(); |