From 8d7e23ea0b6d0e198e445e3cd4285a34d4e7dc96 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 21 May 2014 13:25:26 +0300 Subject: Direct2D QPA: Cache QVectorPaths if drawn more than once Hooking into the caching mechanism gets us a measurable performance boost for paths that are drawn repeatedly, around 10% on my machine when drawing aliased arcs. Change-Id: I32f4ed7daa8a51b5c5a9c6d5414ab5d4ef759f70 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 49 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index a838950c9e..f376f7707f 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -256,8 +256,30 @@ static ComPtr painterPathToID2D1PathGeometry(const QPainterP return writer.geometry(); } -static ComPtr vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias) +struct D2DVectorPathCache { + ComPtr aliased; + ComPtr antiAliased; + + static void cleanup_func(QPaintEngineEx *engine, void *data) { + Q_UNUSED(engine); + D2DVectorPathCache *e = static_cast(data); + delete e; + } +}; + +static ComPtr vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias, QPaintEngineEx* engine) { + QVectorPath::CacheEntry *cacheEntry = path.isCacheable() ? path.lookupCacheData(engine) + : Q_NULLPTR; + + if (cacheEntry) { + D2DVectorPathCache *e = static_cast(cacheEntry->data); + if (alias && e->aliased) + return e->aliased; + else if (!alias && e->antiAliased) + return e->antiAliased; + } + Direct2DPathGeometryWriter writer; if (!writer.begin()) return NULL; @@ -321,7 +343,22 @@ static ComPtr vectorPathToID2D1PathGeometry(const QVectorPat writer.lineTo(QPointF(points[0], points[1])); writer.close(); - return writer.geometry(); + ComPtr geometry = writer.geometry(); + + if (path.isCacheable()) { + if (!cacheEntry) + cacheEntry = path.addCacheData(engine, new D2DVectorPathCache, D2DVectorPathCache::cleanup_func); + + D2DVectorPathCache *e = static_cast(cacheEntry->data); + if (alias) + e->aliased = geometry; + else + e->antiAliased = geometry; + } else { + path.makeCacheable(); + } + + return geometry; } class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate @@ -426,7 +463,7 @@ public: dc()->PushAxisAlignedClip(rect, antialiasMode()); pushedClips.push(AxisAlignedClip); } else { - ComPtr geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, q); if (!geometry) { qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__); return; @@ -938,7 +975,7 @@ void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) { Q_D(QWindowsDirect2DPaintEngine); - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -978,7 +1015,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (!d->brush.brush) return; - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -1016,7 +1053,7 @@ void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pe if (!d->pen.brush) return; - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; -- cgit v1.2.3 From bcab05cb4f35d8bfab3755a4358e6af1adc801f5 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 21 May 2014 14:02:42 +0300 Subject: Direct2D QPA: Get rid of QPainterPath conversion function This function was used only in one place and duplicated a lot of logic with the very similar QVectorPath conversion function. Just use QVectorPath everywhere instead. Change-Id: I3a4821f0452634c309ca0730047ea6ef7a7591ca Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 49 ++-------------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index f376f7707f..18844a2ce5 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -211,51 +211,6 @@ private: bool m_roundCoordinates; }; -static ComPtr painterPathToID2D1PathGeometry(const QPainterPath &path, bool alias) -{ - Direct2DPathGeometryWriter writer; - if (!writer.begin()) - return NULL; - - writer.setWindingFillEnabled(path.fillRule() == Qt::WindingFill); - writer.setAliasingEnabled(alias); - - for (int i = 0; i < path.elementCount(); i++) { - const QPainterPath::Element element = path.elementAt(i); - - switch (element.type) { - case QPainterPath::MoveToElement: - writer.moveTo(element); - break; - - case QPainterPath::LineToElement: - writer.lineTo(element); - break; - - case QPainterPath::CurveToElement: - { - const QPainterPath::Element data1 = path.elementAt(++i); - const QPainterPath::Element data2 = path.elementAt(++i); - - Q_ASSERT(i < path.elementCount()); - - Q_ASSERT(data1.type == QPainterPath::CurveToDataElement); - Q_ASSERT(data2.type == QPainterPath::CurveToDataElement); - - writer.curveTo(element, data1, data2); - } - break; - - case QPainterPath::CurveToDataElement: - qWarning("%s: Unhandled Curve Data Element", __FUNCTION__); - break; - } - } - - writer.close(); - return writer.geometry(); -} - struct D2DVectorPathCache { ComPtr aliased; ComPtr antiAliased; @@ -908,7 +863,9 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev) QPainterPath p; p.addRegion(systemClip()); - ComPtr geometry = painterPathToID2D1PathGeometry(p, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = vectorPathToID2D1PathGeometry(qtVectorPathForPath(p), + d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, + this); if (!geometry) return false; -- cgit v1.2.3 From 26a2fb744866414748ed35a36322460b06911394 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 21 May 2014 14:11:14 +0300 Subject: Direct2D QPA: Move QVectorPath conversion function into private class The function already needs information from the engine for conversion, moving it into the private class makes it possible to get this info directly in the method and makes calling the method nicer. Change-Id: I47fa9a4531d0d0605aa587fba90fbfdf036f0998 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 204 +++++++++++---------- 1 file changed, 103 insertions(+), 101 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 18844a2ce5..3b598b365d 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -222,100 +222,6 @@ struct D2DVectorPathCache { } }; -static ComPtr vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias, QPaintEngineEx* engine) -{ - QVectorPath::CacheEntry *cacheEntry = path.isCacheable() ? path.lookupCacheData(engine) - : Q_NULLPTR; - - if (cacheEntry) { - D2DVectorPathCache *e = static_cast(cacheEntry->data); - if (alias && e->aliased) - return e->aliased; - else if (!alias && e->antiAliased) - return e->antiAliased; - } - - Direct2DPathGeometryWriter writer; - if (!writer.begin()) - return NULL; - - writer.setWindingFillEnabled(path.hasWindingFill()); - writer.setAliasingEnabled(alias); - - const QPainterPath::ElementType *types = path.elements(); - const int count = path.elementCount(); - const qreal *points = path.points(); - - Q_ASSERT(points); - - if (types) { - qreal x, y; - - for (int i = 0; i < count; i++) { - x = points[i * 2]; - y = points[i * 2 + 1]; - - switch (types[i]) { - case QPainterPath::MoveToElement: - writer.moveTo(QPointF(x, y)); - break; - - case QPainterPath::LineToElement: - writer.lineTo(QPointF(x, y)); - break; - - case QPainterPath::CurveToElement: - { - Q_ASSERT((i + 2) < count); - Q_ASSERT(types[i+1] == QPainterPath::CurveToDataElement); - Q_ASSERT(types[i+2] == QPainterPath::CurveToDataElement); - - i++; - const qreal x2 = points[i * 2]; - const qreal y2 = points[i * 2 + 1]; - - i++; - const qreal x3 = points[i * 2]; - const qreal y3 = points[i * 2 + 1]; - - writer.curveTo(QPointF(x, y), QPointF(x2, y2), QPointF(x3, y3)); - } - break; - - case QPainterPath::CurveToDataElement: - qWarning("%s: Unhandled Curve Data Element", __FUNCTION__); - break; - } - } - } else { - writer.moveTo(QPointF(points[0], points[1])); - for (int i = 1; i < count; i++) - writer.lineTo(QPointF(points[i * 2], points[i * 2 + 1])); - } - - if (writer.isInFigure()) - if (path.hasImplicitClose()) - writer.lineTo(QPointF(points[0], points[1])); - - writer.close(); - ComPtr geometry = writer.geometry(); - - if (path.isCacheable()) { - if (!cacheEntry) - cacheEntry = path.addCacheData(engine, new D2DVectorPathCache, D2DVectorPathCache::cleanup_func); - - D2DVectorPathCache *e = static_cast(cacheEntry->data); - if (alias) - e->aliased = geometry; - else - e->antiAliased = geometry; - } else { - path.makeCacheable(); - } - - return geometry; -} - class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate { Q_DECLARE_PUBLIC(QWindowsDirect2DPaintEngine) @@ -418,7 +324,7 @@ public: dc()->PushAxisAlignedClip(rect, antialiasMode()); pushedClips.push(AxisAlignedClip); } else { - ComPtr geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, q); + ComPtr geometry = vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__); return; @@ -827,6 +733,104 @@ public: return result; } + ComPtr vectorPathToID2D1PathGeometry(const QVectorPath &path) + { + Q_Q(QWindowsDirect2DPaintEngine); + + const bool alias = !q->antiAliasingEnabled(); + + QVectorPath::CacheEntry *cacheEntry = path.isCacheable() ? path.lookupCacheData(q) + : Q_NULLPTR; + + if (cacheEntry) { + D2DVectorPathCache *e = static_cast(cacheEntry->data); + if (alias && e->aliased) + return e->aliased; + else if (!alias && e->antiAliased) + return e->antiAliased; + } + + Direct2DPathGeometryWriter writer; + if (!writer.begin()) + return NULL; + + writer.setWindingFillEnabled(path.hasWindingFill()); + writer.setAliasingEnabled(alias); + + const QPainterPath::ElementType *types = path.elements(); + const int count = path.elementCount(); + const qreal *points = path.points(); + + Q_ASSERT(points); + + if (types) { + qreal x, y; + + for (int i = 0; i < count; i++) { + x = points[i * 2]; + y = points[i * 2 + 1]; + + switch (types[i]) { + case QPainterPath::MoveToElement: + writer.moveTo(QPointF(x, y)); + break; + + case QPainterPath::LineToElement: + writer.lineTo(QPointF(x, y)); + break; + + case QPainterPath::CurveToElement: + { + Q_ASSERT((i + 2) < count); + Q_ASSERT(types[i+1] == QPainterPath::CurveToDataElement); + Q_ASSERT(types[i+2] == QPainterPath::CurveToDataElement); + + i++; + const qreal x2 = points[i * 2]; + const qreal y2 = points[i * 2 + 1]; + + i++; + const qreal x3 = points[i * 2]; + const qreal y3 = points[i * 2 + 1]; + + writer.curveTo(QPointF(x, y), QPointF(x2, y2), QPointF(x3, y3)); + } + break; + + case QPainterPath::CurveToDataElement: + qWarning("%s: Unhandled Curve Data Element", __FUNCTION__); + break; + } + } + } else { + writer.moveTo(QPointF(points[0], points[1])); + for (int i = 1; i < count; i++) + writer.lineTo(QPointF(points[i * 2], points[i * 2 + 1])); + } + + if (writer.isInFigure()) + if (path.hasImplicitClose()) + writer.lineTo(QPointF(points[0], points[1])); + + writer.close(); + ComPtr geometry = writer.geometry(); + + if (path.isCacheable()) { + if (!cacheEntry) + cacheEntry = path.addCacheData(q, new D2DVectorPathCache, D2DVectorPathCache::cleanup_func); + + D2DVectorPathCache *e = static_cast(cacheEntry->data); + if (alias) + e->aliased = geometry; + else + e->antiAliased = geometry; + } else { + path.makeCacheable(); + } + + return geometry; + } + void updateHints() { dc()->SetAntialiasMode(antialiasMode()); @@ -863,9 +867,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev) QPainterPath p; p.addRegion(systemClip()); - ComPtr geometry = vectorPathToID2D1PathGeometry(qtVectorPathForPath(p), - d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, - this); + ComPtr geometry = d->vectorPathToID2D1PathGeometry(qtVectorPathForPath(p)); if (!geometry) return false; @@ -932,7 +934,7 @@ void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) { Q_D(QWindowsDirect2DPaintEngine); - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this); + ComPtr geometry = d->vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -972,7 +974,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (!d->brush.brush) return; - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this); + ComPtr geometry = d->vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -1010,7 +1012,7 @@ void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pe if (!d->pen.brush) return; - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED, this); + ComPtr geometry = d->vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; -- cgit v1.2.3 From 9d3b169bda1a48c6eee0820b6a2fd50d6dd6a023 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 21 May 2014 16:42:31 +0300 Subject: Add build support for Windows Phone 8.1 Tweak qmake, add mkspecs for emulator and device, adjust the manifest template for WP8.1, and add missing icons. Change-Id: I7a6405fa85297ae4cc8522015274e65fb7a315a6 Reviewed-by: Oliver Wolff --- .../common/winrt_winphone/assets/logo_44x44.png | Bin 0 -> 1066 bytes .../common/winrt_winphone/assets/logo_480x800.png | Bin 0 -> 6820 bytes .../common/winrt_winphone/assets/logo_71x71.png | Bin 0 -> 1060 bytes .../manifests/8.1_wp/AppxManifest.xml.in | 45 +++++++++++++++++++++ mkspecs/features/winrt/package_manifest.prf | 30 +++++++------- mkspecs/winphone-arm-msvc2013/qmake.conf | 23 +++++++++++ mkspecs/winphone-arm-msvc2013/qplatformdefs.h | 42 +++++++++++++++++++ mkspecs/winphone-x86-msvc2013/qmake.conf | 23 +++++++++++ mkspecs/winphone-x86-msvc2013/qplatformdefs.h | 42 +++++++++++++++++++ qmake/generators/win32/msbuild_objectmodel.cpp | 20 ++++----- qmake/generators/win32/msvc_nmake.cpp | 24 +++++++---- qmake/generators/win32/msvc_objectmodel.cpp | 3 +- qmake/generators/win32/msvc_objectmodel.h | 4 +- qmake/generators/win32/msvc_vcproj.cpp | 5 ++- 14 files changed, 225 insertions(+), 36 deletions(-) create mode 100644 mkspecs/common/winrt_winphone/assets/logo_44x44.png create mode 100644 mkspecs/common/winrt_winphone/assets/logo_480x800.png create mode 100644 mkspecs/common/winrt_winphone/assets/logo_71x71.png create mode 100644 mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in create mode 100644 mkspecs/winphone-arm-msvc2013/qmake.conf create mode 100644 mkspecs/winphone-arm-msvc2013/qplatformdefs.h create mode 100644 mkspecs/winphone-x86-msvc2013/qmake.conf create mode 100644 mkspecs/winphone-x86-msvc2013/qplatformdefs.h diff --git a/mkspecs/common/winrt_winphone/assets/logo_44x44.png b/mkspecs/common/winrt_winphone/assets/logo_44x44.png new file mode 100644 index 0000000000..3cc5bec19f Binary files /dev/null and b/mkspecs/common/winrt_winphone/assets/logo_44x44.png differ diff --git a/mkspecs/common/winrt_winphone/assets/logo_480x800.png b/mkspecs/common/winrt_winphone/assets/logo_480x800.png new file mode 100644 index 0000000000..39a37dac5b Binary files /dev/null and b/mkspecs/common/winrt_winphone/assets/logo_480x800.png differ diff --git a/mkspecs/common/winrt_winphone/assets/logo_71x71.png b/mkspecs/common/winrt_winphone/assets/logo_71x71.png new file mode 100644 index 0000000000..16d0808759 Binary files /dev/null and b/mkspecs/common/winrt_winphone/assets/logo_71x71.png differ diff --git a/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in new file mode 100644 index 0000000000..cf18a4dc79 --- /dev/null +++ b/mkspecs/common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in @@ -0,0 +1,45 @@ + + + + + + $${WINRT_MANIFEST.name} + $${WINRT_MANIFEST.publisher} + $${WINRT_MANIFEST.logo_store} + + + 6.3.1 + 6.3.1 + + + + + + + + + + + + + + + + $${WINRT_MANIFEST.capabilities}$${WINRT_MANIFEST.dependencies} + + diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 444b8b873e..85a6485535 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -14,10 +14,12 @@ # WINRT_MANIFEST.version: The version number of the package. Defaults to "1.0.0.0". # WINRT_MANIFEST.arguments: Allows arguments to be passed to the executable. # WINRT_MANIFEST.publisher: Display name of the publisher. Defaults to "Default publisher display name". -# WINRT_MANIFEST.publisher_id: On Windows 8/RT, the publisher's distinguished name (default: CN=MyCN). On Windows Phone, the publisher's UUID (default: invalid UUID string). +# WINRT_MANIFEST.publisher_id: On Windows 8/RT/Phone 8.1, the publisher's distinguished name (default: CN=MyCN). On Windows Phone 8.0, the publisher's UUID (default: invalid UUID string). +# WINRT_MANIFEST.phone_product_id): On Windows Phone 8.1, the GUID of the product. Defaults to the value of WINRT_MANIFEST.identity. +# WINRT_MANIFEST.phone_publisher_id: On Windows Phone 8.1, the GUID of the publiser. Defaults to an invalid GUID. # WINRT_MANIFEST.description: Package description. Defaults to "Default package description". -# WINRT_MANIFEST.author: Package author (Windows Phone only). Defaults to "Default package author". -# WINRT_MANIFEST.genre: Package genre (Windows Phone only). Defaults to "apps.normal". +# WINRT_MANIFEST.author: Package author (Windows Phone 8.0 only). Defaults to "Default package author". +# WINRT_MANIFEST.genre: Package genre (Windows Phone 8.0 only). Defaults to "apps.normal". # WINRT_MANIFEST.background: Tile background color. Defaults to "green". # WINRT_MANIFEST.foreground: Tile foreground (text) color (Windows 8/RT only). Defaults to "light". # WINRT_MANIFEST.logo_store: Logo image file for Windows Store. Default provided by the mkspec. @@ -49,7 +51,7 @@ BUILD_DIR = $$dirname(QMAKE_RESOLVED_TARGET) } - winphone: \ + winphone:equals(WINSDK_VER, 8.0): \ manifest_file.output = $$BUILD_DIR/WMAppManifest.xml else: contains(TEMPLATE, "vc.*"): \ manifest_file.output = $$BUILD_DIR/Package.appxmanifest @@ -77,16 +79,18 @@ write_file($$UUID_CACHE, WINRT_UUID)|error("Unable to write the UUID cache; aborting.") eval($$WINRT_UUID) } - winphone: WINRT_MANIFEST.identity = {$$WINRT_MANIFEST.identity} + winphone:equals(WINSDK_VER, 8.0): WINRT_MANIFEST.identity = {$$WINRT_MANIFEST.identity} } isEmpty(WINRT_MANIFEST.name): WINRT_MANIFEST.name = $$TARGET isEmpty(WINRT_MANIFEST.architecture): WINRT_MANIFEST.architecture = $$VCPROJ_ARCH isEmpty(WINRT_MANIFEST.version): WINRT_MANIFEST.version = 1.0.0.0 isEmpty(WINRT_MANIFEST.publisher): WINRT_MANIFEST.publisher = Default publisher display name isEmpty(WINRT_MANIFEST.publisherid) { - winphone: WINRT_MANIFEST.publisherid = {00000000-0000-0000-0000-000000000000} + winphone:equals(WINSDK_VER, 8.0): WINRT_MANIFEST.publisherid = {00000000-0000-0000-0000-000000000000} else: WINRT_MANIFEST.publisherid = CN=$$(USERNAME) } + isEmpty(WINRT_MANIFEST.phone_product_id): WINRT_MANIFEST.phone_product_id = $$WINRT_MANIFEST.identity + isEmpty(WINRT_MANIFEST.phone_publisher_id): WINRT_MANIFEST.phone_publisher_id = 00000000-0000-0000-0000-000000000000 isEmpty(WINRT_MANIFEST.description): WINRT_MANIFEST.description = Default package description isEmpty(WINRT_MANIFEST.author): WINRT_MANIFEST.author = Default package author isEmpty(WINRT_MANIFEST.genre): WINRT_MANIFEST.genre = apps.normal @@ -94,7 +98,7 @@ isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en - winphone: INDENT = "$$escape_expand(\\r\\n) " + winphone:equals(WINSDK_VER, 8.0): INDENT = "$$escape_expand(\\r\\n) " else: INDENT = "$$escape_expand(\\r\\n) " # Languages are given as a string list @@ -142,16 +146,12 @@ ICONS_FOUND ~= s/.*\\\$\\\$\\{WINRT_MANIFEST\\.((logo|tile)_[^\}]+)\\}.*/\\1/g for (ICON_NAME, ICONS_FOUND) { ICON_FILE = $$eval(WINRT_MANIFEST.$$ICON_NAME) - isEmpty(ICON_FILE) { - icon_$${ICON_NAME}.input = $$WINRT_ASSETS_PATH/$${ICON_NAME}.png - icon_$${ICON_NAME}.output = $$BUILD_DIR/assets/$${ICON_NAME}.png - WINRT_MANIFEST.$${ICON_NAME} = assets/$${ICON_NAME}.png - } else { - icon_$${ICON_NAME}.input = $$ICON_FILE - icon_$${ICON_NAME}.output = $$BUILD_DIR/$$ICON_FILE - } + isEmpty(ICON_FILE): ICON_FILE = $$WINRT_ASSETS_PATH/$${ICON_NAME}.png + icon_$${ICON_NAME}.input = $$ICON_FILE + icon_$${ICON_NAME}.output = $$BUILD_DIR/assets/$$basename(ICON_FILE) icon_$${ICON_NAME}.CONFIG = verbatim QMAKE_SUBSTITUTES += icon_$${ICON_NAME} + WINRT_MANIFEST.$${ICON_NAME} = assets/$$basename(ICON_FILE) } QMAKE_SUBSTITUTES += manifest_file diff --git a/mkspecs/winphone-arm-msvc2013/qmake.conf b/mkspecs/winphone-arm-msvc2013/qmake.conf new file mode 100644 index 0000000000..e848d254d4 --- /dev/null +++ b/mkspecs/winphone-arm-msvc2013/qmake.conf @@ -0,0 +1,23 @@ +# +# qmake configuration for winphone-arm-msvc2013 +# +# Written for Microsoft Visual C++ 2013 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1800 +QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP ARM __ARM__ __ARM__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += WindowsPhoneCore.lib PhoneAppModelHost.lib + +VCPROJ_ARCH = ARM +MSVC_VER = 12.0 +WINSDK_VER = 8.1 +WINTARGET_VER = WP81 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in +WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winphone-arm-msvc2013/qplatformdefs.h b/mkspecs/winphone-arm-msvc2013/qplatformdefs.h new file mode 100644 index 0000000000..59fb5871ab --- /dev/null +++ b/mkspecs/winphone-arm-msvc2013/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winphone-x86-msvc2013/qmake.conf b/mkspecs/winphone-x86-msvc2013/qmake.conf new file mode 100644 index 0000000000..18d8402822 --- /dev/null +++ b/mkspecs/winphone-x86-msvc2013/qmake.conf @@ -0,0 +1,23 @@ +# +# qmake configuration for winphone-x86-msvc2013 +# +# Written for Microsoft Visual C++ 2013 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1800 +QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X86 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += WindowsPhoneCore.lib PhoneAppModelHost.lib + +VCPROJ_ARCH = Win32 +MSVC_VER = 12.0 +WINSDK_VER = 8.1 +WINTARGET_VER = WP81 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.1_wp/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winphone-x86-msvc2013/qplatformdefs.h b/mkspecs/winphone-x86-msvc2013/qplatformdefs.h new file mode 100644 index 0000000000..59fb5871ab --- /dev/null +++ b/mkspecs/winphone-x86-msvc2013/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index feef587ee6..5fdfc52dba 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -615,7 +615,8 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << attrTag("Label", "ProjectConfigurations"); bool isWinRT = false; - bool isPhone = false; + bool isWinPhone = false; + bool isWinPhone80 = false; // ### Windows Phone 8.0, remove in Qt 5.4 for (int i = 0; i < tool.SingleProjects.count(); ++i) { xml << tag("ProjectConfiguration") << attrTag("Include" , tool.SingleProjects.at(i).Configuration.Name) @@ -623,7 +624,8 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("Platform", tool.SingleProjects.at(i).PlatformName) << closetag(); isWinRT = isWinRT || tool.SingleProjects.at(i).Configuration.WinRT; - isPhone = isPhone || tool.SingleProjects.at(i).Configuration.WinPhone; + isWinPhone = isWinPhone = tool.SingleProjects.at(i).Configuration.WinPhone; + isWinPhone80 = isWinPhone80 || tool.SingleProjects.at(i).Configuration.WinPhone80; } xml << closetag() @@ -635,7 +637,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) if (isWinRT) { xml << tagValue("MinimumVisualStudioVersion", tool.Version); - if (isPhone) { + if (isWinPhone80) { xml << tagValue("WinMDAssembly", "true"); if (tool.SingleProjects.at(0).Configuration.ConfigurationType == typeApplication) { xml << tagValue("XapOutputs", "true"); @@ -643,7 +645,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) } } else { xml << tagValue("AppContainerApplication", "true") - << tagValue("ApplicationType", "Windows Store") + << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") << tagValue("ApplicationTypeRevision", tool.SdkVersion); } } @@ -823,7 +825,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) } outputFilter(tool, xml, xmlFilter, "Root Files"); - if (tool.SingleProjects.at(0).Configuration.WinPhone) { + if (isWinPhone80) { xml << tag("ItemGroup") << tag("Reference") << attrTag("Include", "platform") @@ -835,7 +837,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) // App manifest if (isWinRT) { - QString manifest = isPhone ? QStringLiteral("WMAppManifest.xml") : QStringLiteral("Package.appxmanifest"); + QString manifest = isWinPhone80 ? QStringLiteral("WMAppManifest.xml") : QStringLiteral("Package.appxmanifest"); // Find all icons referenced in the manifest QSet icons; @@ -856,7 +858,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) // Write out manifest + icons as content items xml << tag(_ItemGroup) - << tag(isPhone ? "Xml" : "AppxManifest") + << tag(isWinPhone80 ? "Xml" : "AppxManifest") << attrTag("Include", manifest) << closetag(); foreach (const QString &icon, icons) { @@ -869,7 +871,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); - if (isPhone) + if (isWinPhone80) xml << import("Project", "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v8.0\\Microsoft.Cpp.WindowsPhone.8.0.targets"); xml << tag("ImportGroup") diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index b8a564968d..4239ceb90f 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -166,10 +166,17 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return false; } - regKey = regKeyPrefix - + (isPhone ? QStringLiteral("Microsoft\\Microsoft SDKs\\WindowsPhone\\v") - : QStringLiteral("Microsoft\\Microsoft SDKs\\Windows\\v")) - + winsdkVer + QStringLiteral("\\InstallationFolder"); + QString windowsPath; + if (isPhone) { + if (targetVer == "WP80") // ### Windows Phone 8.0, remove in Qt 5.4 + windowsPath = "Microsoft\\Microsoft SDKs\\WindowsPhone\\v"; + else + windowsPath = "Microsoft\\Microsoft SDKs\\WindowsPhoneApp\\v"; + } else { + windowsPath = "Microsoft\\Microsoft SDKs\\Windows\\v"; + } + + regKey = regKeyPrefix + windowsPath + winsdkVer + QStringLiteral("\\InstallationFolder"); const QString kitDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey); if (kitDir.isEmpty()) { fprintf(stderr, "Failed to find the Windows Kit installation directory.\n"); @@ -184,7 +191,9 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QStringList libDirs; QStringList binDirs; if (isPhone) { - QString sdkDir = vcInstallDir + QStringLiteral("/WPSDK/") + targetVer; + QString sdkDir = vcInstallDir; + if (targetVer == "WP80") + sdkDir += QStringLiteral("/WPSDK/") + targetVer; if (!QDir(sdkDir).exists()) { fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n" "Check that it is properly installed.\n", @@ -192,7 +201,8 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return false; } incDirs << sdkDir + QStringLiteral("/include"); - libDirs << sdkDir + QStringLiteral("/lib/") + compilerArch; + libDirs << sdkDir + QStringLiteral("/lib/store/") + compilerArch + << sdkDir + QStringLiteral("/lib/") + compilerArch; binDirs << sdkDir + QStringLiteral("/bin/") + compiler; libDirs << kitDir + QStringLiteral("/lib/") + arch; incDirs << kitDir + QStringLiteral("/include") diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 633682baf4..b2663e51c9 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -2129,6 +2129,7 @@ VCPreLinkEventTool::VCPreLinkEventTool() VCConfiguration::VCConfiguration() : WinRT(false), WinPhone(false), + WinPhone80(false), ATLMinimizesCRunTimeLibraryUsage(unset), BuildBrowserInformation(unset), CharacterSet(charSetNotSet), diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index ac96d55de1..9a57a2c7a2 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -886,7 +886,7 @@ public: ~VCConfiguration(){} DotNET CompilerVersion; - bool WinRT, WinPhone; + bool WinRT, WinPhone, WinPhone80; // Variables triState ATLMinimizesCRunTimeLibraryUsage; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 2bd3301e16..a28ddd63c4 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -902,7 +902,7 @@ void VcprojGenerator::initProject() initResourceFiles(); initExtraCompilerOutputs(); if (vcProject.Configuration.WinRT) { - if (vcProject.Configuration.WinPhone + if (vcProject.Configuration.WinPhone80 && vcProject.Configuration.ConfigurationType == typeApplication) initWMAppManifest(); } @@ -1012,6 +1012,7 @@ void VcprojGenerator::initConfiguration() conf.WinRT = project->isActiveConfig("winrt"); if (conf.WinRT) { conf.WinPhone = project->isActiveConfig("winphone"); + conf.WinPhone80 = project->first("WINTARGET_VER") == "WP80"; // Saner defaults conf.compiler.UsePrecompiledHeader = pchNone; conf.compiler.CompileAsWinRT = _False; -- cgit v1.2.3 From 4c9eb38390b35ee3ec0dc966e0b5036cac5ac76b Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 16 May 2014 10:22:47 +0300 Subject: Support Windows Phone 8.1 in WinRT QPA - Unsupported code paths for WP8.0 are avoided, and new APIs are used where appropriate (virtual keyboard) - DirectWrite fonts are loaded on WP8.1 - Platform dialogs are used on WP8.1 Change-Id: I721006ac943ad4e248f0f1590ce247a03e40fbc0 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtfontdatabase.cpp | 10 ++-- src/plugins/platforms/winrt/qwinrtfontdatabase.h | 6 +-- src/plugins/platforms/winrt/qwinrtinputcontext.cpp | 53 +++++++++++++++++++++- .../platforms/winrt/qwinrtplatformtheme.cpp | 10 ++-- src/plugins/platforms/winrt/winrt.pro | 8 ++-- 5 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 70bb9469db..7de223bbed 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp @@ -44,13 +44,13 @@ #include #include -#ifndef Q_OS_WINPHONE +#ifdef QT_WINRT_USE_DWRITE #include #include #include #include using namespace Microsoft::WRL; -#endif // !Q_OS_WINPHONE +#endif // QT_WINRT_USE_DWRITE QT_BEGIN_NAMESPACE @@ -62,7 +62,7 @@ QString QWinRTFontDatabase::fontDir() const const QString applicationDirPath = QCoreApplication::applicationDirPath(); fontDirectory = applicationDirPath + QLatin1String("/fonts"); if (!QFile::exists(fontDirectory)) { -#ifndef Q_OS_WINPHONE +#ifdef QT_WINRT_USE_DWRITE if (m_fontFamilies.isEmpty()) #endif qWarning("No fonts directory found in application package."); @@ -72,7 +72,7 @@ QString QWinRTFontDatabase::fontDir() const return fontDirectory; } -#ifndef Q_OS_WINPHONE +#ifdef QT_WINRT_USE_DWRITE QWinRTFontDatabase::~QWinRTFontDatabase() { @@ -398,6 +398,6 @@ void QWinRTFontDatabase::releaseHandle(void *handle) QBasicFontDatabase::releaseHandle(handle); } -#endif // !Q_OS_WINPHONE +#endif // QT_WINRT_USE_DWRITE QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h index b318a95502..19bf6fa9cf 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE -#ifndef Q_OS_WINPHONE +#ifdef QT_WINRT_USE_DWRITE struct IDWriteFontFile; struct IDWriteFontFamily; @@ -61,7 +61,7 @@ class QWinRTFontDatabase : public QBasicFontDatabase { public: QString fontDir() const; -#ifndef Q_OS_WINPHONE +#ifdef QT_WINRT_USE_DWRITE ~QWinRTFontDatabase(); QFont defaultFont() const Q_DECL_OVERRIDE; void populateFontDatabase() Q_DECL_OVERRIDE; @@ -71,7 +71,7 @@ public: private: QHash m_fonts; QHash m_fontFamilies; -#endif // !Q_OS_WINPHONE +#endif // QT_WINRT_USE_DWRITE }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index bc15f1e448..8e1728dc04 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -52,7 +52,7 @@ using namespace ABI::Windows::Foundation; using namespace ABI::Windows::UI::ViewManagement; using namespace ABI::Windows::UI::Core; -#ifdef Q_OS_WINPHONE +#if defined(Q_OS_WINPHONE) && _MSC_VER==1700 #include using namespace ABI::Windows::Phone::UI::Core; #endif @@ -148,22 +148,73 @@ void QWinRTInputContext::setKeyboardRect(const QRectF rect) #ifdef Q_OS_WINPHONE +#if _MSC_VER>1700 // Windows Phone 8.1+ +static HRESULT getInputPane(ComPtr *inputPane2) +{ + ComPtr factory; + HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(), + &factory); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get input pane factory."); + return hr; + } + + ComPtr inputPane; + hr = factory->GetForCurrentView(&inputPane); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get input pane."); + return hr; + } + + hr = inputPane.As(inputPane2); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get extended input pane."); + return hr; + } + return hr; +} +#endif // _MSC_VER>1700 + void QWinRTInputContext::showInputPanel() { +#if _MSC_VER<=1700 // Windows Phone 8.0 ICoreWindowKeyboardInput *input; if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) { input->put_IsKeyboardInputEnabled(true); input->Release(); } +#else // _MSC_VER<=1700 + ComPtr inputPane; + HRESULT hr = getInputPane(&inputPane); + if (FAILED(hr)) + return; + + boolean success; + hr = inputPane->TryShow(&success); + if (FAILED(hr)) + qErrnoWarning(hr, "Failed to show input panel."); +#endif // _MSC_VER>1700 } void QWinRTInputContext::hideInputPanel() { +#if _MSC_VER<=1700 // Windows Phone 8.0 ICoreWindowKeyboardInput *input; if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) { input->put_IsKeyboardInputEnabled(false); input->Release(); } +#else // _MSC_VER<=1700 + ComPtr inputPane; + HRESULT hr = getInputPane(&inputPane); + if (FAILED(hr)) + return; + + boolean success; + hr = inputPane->TryHide(&success); + if (FAILED(hr)) + qErrnoWarning(hr, "Failed to hide input panel."); +#endif // _MSC_VER>1700 } #else // Q_OS_WINPHONE diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp index 2c8d33da84..e8f853e4b1 100644 --- a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp +++ b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp @@ -50,25 +50,25 @@ QWinRTPlatformTheme::QWinRTPlatformTheme() bool QWinRTPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const { -#ifndef Q_OS_WINPHONE +#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700) if (type == QPlatformTheme::MessageDialog) return true; -#endif // Q_OS_WINPHONE +#endif // !(Q_OS_WINPHONE && _MSC_VER<=1700) return false; } QPlatformDialogHelper *QWinRTPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const { -#ifndef Q_OS_WINPHONE +#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700) switch (type) { case QPlatformTheme::MessageDialog: return new QWinRTPlatformMessageDialogHelper(); default: return QPlatformTheme::createPlatformDialogHelper(type); } -#else +#else // !(Q_OS_WINPHONE && _MSC_VER<=1700) return QPlatformTheme::createPlatformDialogHelper(type); -#endif // Q_OS_WINPHONE +#endif // Q_OS_WINPHONE && _MSC_VER<=1700 } QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 0122bf9475..349cdf11c9 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -3,8 +3,7 @@ CONFIG -= precompile_header # For Windows Phone 8 we have to deploy fonts together with the application as DirectWrite # is not supported here. -# TODO: Add a condition/remove this block if Windows Phone 8.1 supports DirectWrite -winphone { +winphone:equals(WINSDK_VER, 8.0): { fonts.path = $$[QT_INSTALL_LIBS]/fonts fonts.files = $$QT_SOURCE_TREE/lib/fonts/DejaVu*.ttf INSTALLS += fonts @@ -21,9 +20,10 @@ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES LIBS += $$QMAKE_LIBS_CORE -!winphone { +!if(winphone:equals(WINSDK_VER, 8.0)) { LIBS += -ldwrite INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include + DEFINES += QT_WINRT_USE_DWRITE } SOURCES = \ @@ -70,7 +70,7 @@ fxc_blitvs.variable_out = HEADERS fxc_blitvs.CONFIG += target_predeps QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs -winphone { +winphone:equals(WINSDK_VER, 8.0): { SOURCES -= qwinrtplatformmessagedialoghelper.cpp HEADERS -= qwinrtplatformmessagedialoghelper.h } -- cgit v1.2.3 From c32295eb8008c01b422fc04839b22e914786704f Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 21 May 2014 00:59:44 +0300 Subject: ANGLE WinRT: Create swap chain using physical resolution ANGLE has been creating the framebuffer in logical pixels instead of physical pixels, which leads to unexpected results and side effects like smudged anti-aliased text. This fixes the issue by multiplying the DIP resolution by the scale factor, making the framebuffer match the physical pixel resolution of the screen. Change-Id: I3594995ce8e18a31b47e27165f72bc6a391b97b6 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/3rdparty/angle/src/libEGL/Surface.cpp | 97 ++++++++++++-- ...-Create-swap-chain-using-physical-resolut.patch | 145 +++++++++++++++++++++ 2 files changed, 228 insertions(+), 14 deletions(-) create mode 100644 src/angle/patches/0018-ANGLE-WinRT-Create-swap-chain-using-physical-resolut.patch diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp index 3443355c07..a2e2306ae5 100644 --- a/src/3rdparty/angle/src/libEGL/Surface.cpp +++ b/src/3rdparty/angle/src/libEGL/Surface.cpp @@ -24,8 +24,83 @@ #include "libEGL/Display.h" #if defined(ANGLE_OS_WINRT) +#include #include #include +#include + +static bool getCoreWindowSize(const EGLNativeWindowType win, int *width, int *height) +{ + Microsoft::WRL::ComPtr window; + HRESULT hr = win->QueryInterface(IID_PPV_ARGS(&window)); + if (FAILED(hr)) + { + ERR("Failed to cast native display pointer to ICoreWindow *."); + return false; + } + +#if _MSC_VER<=1700 + Microsoft::WRL::ComPtr displayInformation; + hr = RoGetActivationFactory(Microsoft::WRL::Wrappers::HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), + IID_PPV_ARGS(&displayInformation)); +#else + Microsoft::WRL::ComPtr displayInformationFactory; + hr = RoGetActivationFactory(Microsoft::WRL::Wrappers::HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), + IID_PPV_ARGS(&displayInformationFactory)); + if (FAILED(hr)) + { + ERR("Failed to get display information factory."); + return false; + } + + Microsoft::WRL::ComPtr displayInformation; + hr = displayInformationFactory->GetForCurrentView(&displayInformation); +#endif + if (FAILED(hr)) + { + ERR("Failed to get display information."); + return false; + } + +#if defined(ANGLE_OS_WINPHONE) && _MSC_VER>=1800 // Windows Phone 8.1 + Microsoft::WRL::ComPtr displayInformation2; + hr = displayInformation.As(&displayInformation2); + if (FAILED(hr)) + { + ERR("Failed to get extended display information."); + return false; + } + + DOUBLE scaleFactor; + hr = displayInformation2->get_RawPixelsPerViewPixel(&scaleFactor); + if (FAILED(hr)) + { + ERR("Failed to get raw pixels per view pixel."); + return false; + } +#else + ABI::Windows::Graphics::Display::ResolutionScale resolutionScale; + hr = displayInformation->get_ResolutionScale(&resolutionScale); + if (FAILED(hr)) + { + ERR("Failed to get resolution scale."); + return false; + } + DOUBLE scaleFactor = DOUBLE(resolutionScale) / 100.0; +#endif + + ABI::Windows::Foundation::Rect windowRect; + hr = window->get_Bounds(&windowRect); + if (FAILED(hr)) + { + ERR("Failed to get ICoreWindow bounds."); + return false; + } + + *width = std::floor(windowRect.Width * scaleFactor + 0.5); + *height = std::floor(windowRect.Height * scaleFactor + 0.5); + return true; +} #endif namespace egl @@ -117,14 +192,10 @@ bool Surface::resetSwapChain() width = windowRect.right - windowRect.left; height = windowRect.bottom - windowRect.top; #else - ABI::Windows::Foundation::Rect windowRect; - ABI::Windows::UI::Core::ICoreWindow *window; - HRESULT hr = mWindow->QueryInterface(IID_PPV_ARGS(&window)); - if (FAILED(hr)) + if (!getCoreWindowSize(mWindow, &width, &height)) + { return false; - window->get_Bounds(&windowRect); - width = windowRect.Width; - height = windowRect.Height; + } #endif } else @@ -336,14 +407,12 @@ bool Surface::checkForOutOfDateSwapChain() int clientWidth = client.right - client.left; int clientHeight = client.bottom - client.top; #else - ABI::Windows::Foundation::Rect windowRect; - ABI::Windows::UI::Core::ICoreWindow *window; - HRESULT hr = mWindow->QueryInterface(IID_PPV_ARGS(&window)); - if (FAILED(hr)) + int clientWidth; + int clientHeight; + if (!getCoreWindowSize(mWindow, &clientWidth, &clientHeight)) + { return false; - window->get_Bounds(&windowRect); - int clientWidth = windowRect.Width; - int clientHeight = windowRect.Height; + } #endif bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); diff --git a/src/angle/patches/0018-ANGLE-WinRT-Create-swap-chain-using-physical-resolut.patch b/src/angle/patches/0018-ANGLE-WinRT-Create-swap-chain-using-physical-resolut.patch new file mode 100644 index 0000000000..d46851b1e8 --- /dev/null +++ b/src/angle/patches/0018-ANGLE-WinRT-Create-swap-chain-using-physical-resolut.patch @@ -0,0 +1,145 @@ +From 59c6d4c94acb4735a73f50f46f91a6cce7389f94 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Wed, 21 May 2014 00:58:21 +0300 +Subject: [PATCH] ANGLE WinRT: Create swap chain using physical resolution + +ANGLE has been creating the framebuffer in logical pixels instead of +physical pixels, which leads to unexpected results and side effects like +smudged anti-aliased text. This fixes the issue by multiplying the DIP +resolution by the scale factor, making the framebuffer match the physical +pixel resolution of the screen. + +Change-Id: I3594995ce8e18a31b47e27165f72bc6a391b97b6 +--- + src/3rdparty/angle/src/libEGL/Surface.cpp | 97 ++++++++++++++++++++++++++----- + 1 file changed, 83 insertions(+), 14 deletions(-) + +diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp +index 3443355..a2e2306 100644 +--- a/src/3rdparty/angle/src/libEGL/Surface.cpp ++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp +@@ -24,8 +24,83 @@ + #include "libEGL/Display.h" + + #if defined(ANGLE_OS_WINRT) ++#include + #include + #include ++#include ++ ++static bool getCoreWindowSize(const EGLNativeWindowType win, int *width, int *height) ++{ ++ Microsoft::WRL::ComPtr window; ++ HRESULT hr = win->QueryInterface(IID_PPV_ARGS(&window)); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to cast native display pointer to ICoreWindow *."); ++ return false; ++ } ++ ++#if _MSC_VER<=1700 ++ Microsoft::WRL::ComPtr displayInformation; ++ hr = RoGetActivationFactory(Microsoft::WRL::Wrappers::HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), ++ IID_PPV_ARGS(&displayInformation)); ++#else ++ Microsoft::WRL::ComPtr displayInformationFactory; ++ hr = RoGetActivationFactory(Microsoft::WRL::Wrappers::HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), ++ IID_PPV_ARGS(&displayInformationFactory)); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to get display information factory."); ++ return false; ++ } ++ ++ Microsoft::WRL::ComPtr displayInformation; ++ hr = displayInformationFactory->GetForCurrentView(&displayInformation); ++#endif ++ if (FAILED(hr)) ++ { ++ ERR("Failed to get display information."); ++ return false; ++ } ++ ++#if defined(ANGLE_OS_WINPHONE) && _MSC_VER>=1800 // Windows Phone 8.1 ++ Microsoft::WRL::ComPtr displayInformation2; ++ hr = displayInformation.As(&displayInformation2); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to get extended display information."); ++ return false; ++ } ++ ++ DOUBLE scaleFactor; ++ hr = displayInformation2->get_RawPixelsPerViewPixel(&scaleFactor); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to get raw pixels per view pixel."); ++ return false; ++ } ++#else ++ ABI::Windows::Graphics::Display::ResolutionScale resolutionScale; ++ hr = displayInformation->get_ResolutionScale(&resolutionScale); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to get resolution scale."); ++ return false; ++ } ++ DOUBLE scaleFactor = DOUBLE(resolutionScale) / 100.0; ++#endif ++ ++ ABI::Windows::Foundation::Rect windowRect; ++ hr = window->get_Bounds(&windowRect); ++ if (FAILED(hr)) ++ { ++ ERR("Failed to get ICoreWindow bounds."); ++ return false; ++ } ++ ++ *width = std::floor(windowRect.Width * scaleFactor + 0.5); ++ *height = std::floor(windowRect.Height * scaleFactor + 0.5); ++ return true; ++} + #endif + + namespace egl +@@ -117,14 +192,10 @@ bool Surface::resetSwapChain() + width = windowRect.right - windowRect.left; + height = windowRect.bottom - windowRect.top; + #else +- ABI::Windows::Foundation::Rect windowRect; +- ABI::Windows::UI::Core::ICoreWindow *window; +- HRESULT hr = mWindow->QueryInterface(IID_PPV_ARGS(&window)); +- if (FAILED(hr)) ++ if (!getCoreWindowSize(mWindow, &width, &height)) ++ { + return false; +- window->get_Bounds(&windowRect); +- width = windowRect.Width; +- height = windowRect.Height; ++ } + #endif + } + else +@@ -336,14 +407,12 @@ bool Surface::checkForOutOfDateSwapChain() + int clientWidth = client.right - client.left; + int clientHeight = client.bottom - client.top; + #else +- ABI::Windows::Foundation::Rect windowRect; +- ABI::Windows::UI::Core::ICoreWindow *window; +- HRESULT hr = mWindow->QueryInterface(IID_PPV_ARGS(&window)); +- if (FAILED(hr)) ++ int clientWidth; ++ int clientHeight; ++ if (!getCoreWindowSize(mWindow, &clientWidth, &clientHeight)) ++ { + return false; +- window->get_Bounds(&windowRect); +- int clientWidth = windowRect.Width; +- int clientHeight = windowRect.Height; ++ } + #endif + bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); + +-- +1.9.0.msysgit.0 + -- cgit v1.2.3 From eea02ff10da0ff6bba665df560c5404477b9f550 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Thu, 22 May 2014 08:54:14 +0300 Subject: WinRT: Support High-DPI Previously, the backing store and default framebuffer were created with the logical screen resolution (in device-independent pixels), not the the physical screen resolution. This lead to blurry text on high-DPI devices. This change fixes this by creating those at full size, and setting the device pixel ratio appropriately. Windows are still reported in device-independent pixels, but text and images are now rendered sharply for Qt Quick applications. As QPainter does not support non-integer scaling, the backing store is still drawn in DIPs and scaled by OpenGL. Task-number: QTBUG-38464 Change-Id: I7377d4c734126825d670b8ebb65fd0dd1ef705f2 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 22 +-- src/plugins/platforms/winrt/qwinrtbackingstore.h | 3 +- src/plugins/platforms/winrt/qwinrtscreen.cpp | 155 +++++++++++++++++---- src/plugins/platforms/winrt/qwinrtscreen.h | 22 ++- src/plugins/platforms/winrt/qwinrtwindow.cpp | 5 + src/plugins/platforms/winrt/qwinrtwindow.h | 2 + 6 files changed, 171 insertions(+), 38 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index 9b623048af..b8418eef6a 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -284,7 +284,7 @@ QWinRTBackingStore::~QWinRTBackingStore() QPaintDevice *QWinRTBackingStore::paintDevice() { - return m_paintDevice.data(); + return &m_paintDevice; } void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) @@ -293,8 +293,6 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo if (m_size.isEmpty()) return; - const QImage *image = static_cast(m_paintDevice.data()); - m_context->makeCurrent(window); // Blitting the entire image width trades zero image copy/relayout for a larger texture upload. @@ -307,7 +305,7 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo glBindTexture(GL_TEXTURE_2D, m_texture); QRect bounds = region.boundingRect(); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(), - GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y())); + GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_paintDevice.constScanLine(bounds.y())); // TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads //glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine()); //glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(), @@ -325,7 +323,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords); // Render - glViewport(0, 0, m_size.width(), m_size.height()); + const QSize blitSize = m_size * window->devicePixelRatio(); + glViewport(0, 0, blitSize.width(), blitSize.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // Unbind @@ -338,8 +337,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo // fast blit - TODO: perform the blit inside swap buffers instead glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0); - glBlitFramebufferANGLE(0, 0, m_size.width(), m_size.height(), // TODO: blit only the changed rectangle - 0, 0, m_size.width(), m_size.height(), + glBlitFramebufferANGLE(0, 0, blitSize.width(), blitSize.height(), // TODO: blit only the changed rectangle + 0, 0, blitSize.width(), blitSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); m_context->swapBuffers(window); @@ -359,21 +358,22 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents if (m_size.isEmpty()) return; - m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied)); + m_paintDevice = QImage(m_size, QImage::Format_ARGB32_Premultiplied); m_context->makeCurrent(window()); // Input texture glBindTexture(GL_TEXTURE_2D, m_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); // Render buffer glBindRenderbuffer(GL_RENDERBUFFER, m_rbo); - glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, m_size.width(), m_size.height()); + const QSize blitSize = m_size * window()->devicePixelRatio(); + glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, blitSize.width(), blitSize.height()); glBindRenderbuffer(GL_RENDERBUFFER, 0); m_context->doneCurrent(); } diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h index 726f7c838f..f00fa85a26 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.h +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h @@ -60,18 +60,19 @@ public: void endPaint(); void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); + QImage toImage() const Q_DECL_OVERRIDE { return m_paintDevice; } private: bool initialize(); bool m_initialized; QSize m_size; - QScopedPointer m_paintDevice; QScopedPointer m_context; quint32 m_shaderProgram; quint32 m_fbo; quint32 m_rbo; quint32 m_texture; QWinRTScreen *m_screen; + QImage m_paintDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index e2ff7197aa..3fe856558f 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -93,6 +93,11 @@ typedef ITypedEventHandler PointerHandler; typedef ITypedEventHandler SizeChangedHandler; typedef ITypedEventHandler VisibilityChangedHandler; typedef ITypedEventHandler AutomationProviderRequestedHandler; +#if _MSC_VER <=1700 +typedef IDisplayPropertiesEventHandler DisplayInformationHandler; +#else +typedef ITypedEventHandler DisplayInformationHandler; +#endif #ifdef Q_OS_WINPHONE typedef IEventHandler BackPressedHandler; #endif @@ -424,12 +429,13 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window) , m_inputContext(Make(m_coreWindow).Detach()) #endif , m_cursor(new QWinRTCursor(window)) + , m_devicePixelRatio(1.0) , m_orientation(Qt::PrimaryOrientation) , m_touchDevice(Q_NULLPTR) { Rect rect; window->get_Bounds(&rect); - m_geometry = QRect(0, 0, rect.Width, rect.Height); + m_geometry = QRectF(0, 0, rect.Width, rect.Height); m_surfaceFormat.setAlphaBufferSize(0); m_surfaceFormat.setRedBufferSize(8); @@ -478,26 +484,63 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window) m_coreWindow->add_AutomationProviderRequested(Callback(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]); // Orientation handling - if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), - &m_displayProperties))) { - // Set native orientation - DisplayOrientations displayOrientation; - m_displayProperties->get_NativeOrientation(&displayOrientation); - m_nativeOrientation = static_cast(static_cast(qtOrientationsFromNative(displayOrientation))); - - // Set initial orientation - onOrientationChanged(0); - setOrientationUpdateMask(m_nativeOrientation); - - m_displayProperties->add_OrientationChanged(Callback(this, &QWinRTScreen::onOrientationChanged).Get(), - &m_tokens[QEvent::OrientationChange]); +#if _MSC_VER<=1700 + HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), + &m_displayInformation); +#else + HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), + &m_displayInformationFactory); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get display information factory."); + return; } -#ifndef Q_OS_WINPHONE - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), - &m_applicationView); + hr = m_displayInformationFactory->GetForCurrentView(&m_displayInformation); #endif + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get display information for the current view."); + return; + } + + // Set native orientation + DisplayOrientations displayOrientation; + hr = m_displayInformation->get_NativeOrientation(&displayOrientation); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get native orientation."); + return; + } + + m_nativeOrientation = static_cast(static_cast(qtOrientationsFromNative(displayOrientation))); + + hr = m_displayInformation->add_OrientationChanged(Callback(this, &QWinRTScreen::onOrientationChanged).Get(), + &m_tokens[QEvent::OrientationChange]); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to add orientation change callback."); + return; + } + +#if _MSC_VER<=1700 + hr = m_displayInformation->add_LogicalDpiChanged(Callback(this, &QWinRTScreen::onDpiChanged).Get(), + &m_tokens[QEvent::Type(QEvent::User + 1)]); +#else + hr = m_displayInformation->add_DpiChanged(Callback(this, &QWinRTScreen::onDpiChanged).Get(), + &m_tokens[QEvent::Type(QEvent::User + 1)]); +#endif + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to add logical dpi change callback."); + return; + } + + // Set initial orientation & pixel density +#if _MSC_VER<=1700 + onOrientationChanged(Q_NULLPTR); + onDpiChanged(Q_NULLPTR); +#else + onOrientationChanged(Q_NULLPTR, Q_NULLPTR); + onDpiChanged(Q_NULLPTR, Q_NULLPTR); +#endif + setOrientationUpdateMask(m_nativeOrientation); if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), IID_PPV_ARGS(&m_application)))) { @@ -508,7 +551,7 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window) QRect QWinRTScreen::geometry() const { - return m_geometry; + return m_geometry.toRect(); } int QWinRTScreen::depth() const @@ -526,6 +569,21 @@ QSurfaceFormat QWinRTScreen::surfaceFormat() const return m_surfaceFormat; } +QSizeF QWinRTScreen::physicalSize() const +{ + return m_geometry.size() / m_dpi * qreal(25.4); +} + +QDpi QWinRTScreen::logicalDpi() const +{ + return QDpi(m_dpi, m_dpi); +} + +qreal QWinRTScreen::devicePixelRatio() const +{ + return m_devicePixelRatio; +} + QWinRTInputContext *QWinRTScreen::inputContext() const { return m_inputContext; @@ -572,7 +630,11 @@ Qt::ScreenOrientation QWinRTScreen::orientation() const void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) { - m_displayProperties->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); +#if _MSC_VER<=1700 + m_displayInformation->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); +#else + m_displayInformationFactory->put_AutoRotationPreferences(nativeOrientationsFromQt(mask)); +#endif } ICoreWindow *QWinRTScreen::coreWindow() const @@ -637,7 +699,7 @@ void QWinRTScreen::handleExpose() if (m_visibleWindows.isEmpty()) return; QList::const_iterator it = m_visibleWindows.constBegin(); - QWindowSystemInterface::handleExposeEvent(*it, m_geometry); + QWindowSystemInterface::handleExposeEvent(*it, m_geometry.toRect()); while (++it != m_visibleWindows.constEnd()) QWindowSystemInterface::handleExposeEvent(*it, QRegion()); QWindowSystemInterface::flushWindowSystemEvents(); @@ -914,9 +976,9 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEvent // Regardless of state, all top-level windows are viewport-sized - this might change if // a more advanced compositor is written. - m_geometry.setSize(QSize(size.Width, size.Height)); - QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry); + m_geometry.setSize(QSizeF(size.Width, size.Height)); + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry.toRect()); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry.toRect()); QPlatformScreen::resizeMaximizedWindows(); handleExpose(); @@ -981,10 +1043,14 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChange return S_OK; } +#if _MSC_VER<=1700 HRESULT QWinRTScreen::onOrientationChanged(IInspectable *) +#else +HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *) +#endif { DisplayOrientations displayOrientation; - m_displayProperties->get_CurrentOrientation(&displayOrientation); + m_displayInformation->get_CurrentOrientation(&displayOrientation); Qt::ScreenOrientation newOrientation = static_cast(static_cast(qtOrientationsFromNative(displayOrientation))); if (m_orientation != newOrientation) { m_orientation = newOrientation; @@ -994,6 +1060,47 @@ HRESULT QWinRTScreen::onOrientationChanged(IInspectable *) return S_OK; } +#if _MSC_VER<=1700 +HRESULT QWinRTScreen::onDpiChanged(IInspectable *) +#else +HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) +#endif +{ +#if defined(Q_OS_WINPHONE) && _MSC_VER>=1800 // WP 8.1 + ComPtr displayInformation; + HRESULT hr = m_displayInformation->QueryInterface(IID_IDisplayInformation2, &displayInformation); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to cast display information."); + return S_OK; + } + hr = displayInformation->get_RawPixelsPerViewPixel(&m_devicePixelRatio); +#else + ResolutionScale resolutionScale; + HRESULT hr = m_displayInformation->get_ResolutionScale(&resolutionScale); +#endif + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get display resolution scale."); + return S_OK; + } +#if !(defined(Q_OS_WINPHONE) && _MSC_VER>=1800) // !WP8.1 + m_devicePixelRatio = qreal(resolutionScale) / 100; +#endif + + // Correct the scale factor for integer window size + m_devicePixelRatio = m_devicePixelRatio * ((m_geometry.width()/qRound(m_geometry.width()) + + m_geometry.height()/qRound(m_geometry.height())) / 2.0); + + FLOAT dpi; + hr = m_displayInformation->get_LogicalDpi(&dpi); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get logical DPI."); + return S_OK; + } + m_dpi = dpi; + + return S_OK; +} + #ifdef Q_OS_WINPHONE HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) { diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 753d89541c..d39683a960 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -78,6 +78,8 @@ namespace ABI { namespace Graphics { namespace Display { struct IDisplayPropertiesStatics; + struct IDisplayInformationStatics; + struct IDisplayInformation; } } #ifdef Q_OS_WINPHONE @@ -109,6 +111,9 @@ public: int depth() const; QImage::Format format() const; QSurfaceFormat surfaceFormat() const; + QSizeF physicalSize() const Q_DECL_OVERRIDE; + QDpi logicalDpi() const Q_DECL_OVERRIDE; + qreal devicePixelRatio() const Q_DECL_OVERRIDE; QWinRTInputContext *inputContext() const; QPlatformCursor *cursor() const; Qt::KeyboardModifiers keyboardModifiers() const; @@ -150,7 +155,13 @@ private: HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args); HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args); +#if _MSC_VER<=1700 HRESULT onOrientationChanged(IInspectable *); + HRESULT onDpiChanged(IInspectable *); +#else + HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); + HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); +#endif #ifdef Q_OS_WINPHONE HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); @@ -160,9 +171,10 @@ private: ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView; ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application; - QRect m_geometry; + QRectF m_geometry; QImage::Format m_format; QSurfaceFormat m_surfaceFormat; + qreal m_dpi; int m_depth; QWinRTInputContext *m_inputContext; QWinRTCursor *m_cursor; @@ -171,7 +183,13 @@ private: EGLDisplay m_eglDisplay; EGLSurface m_eglSurface; - ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayProperties; +#if _MSC_VER<=1700 + ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayInformation; +#else + ABI::Windows::Graphics::Display::IDisplayInformationStatics *m_displayInformationFactory; + ABI::Windows::Graphics::Display::IDisplayInformation *m_displayInformation; +#endif + qreal m_devicePixelRatio; Qt::ScreenOrientation m_nativeOrientation; Qt::ScreenOrientation m_orientation; diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 88b753b463..80ee6bd761 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -116,4 +116,9 @@ void QWinRTWindow::lower() m_screen->lower(window()); } +qreal QWinRTWindow::devicePixelRatio() const +{ + return screen()->devicePixelRatio(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h index 1f19b4f2d5..121f430686 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.h +++ b/src/plugins/platforms/winrt/qwinrtwindow.h @@ -63,6 +63,8 @@ public: void raise(); void lower(); + qreal devicePixelRatio() const Q_DECL_OVERRIDE; + private: QWinRTScreen *m_screen; }; -- cgit v1.2.3 From dd73975beef5bf51f891b5320f102d9f8d85461a Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Fri, 16 May 2014 16:24:22 +0300 Subject: WinRT app manifest: update namespace prefix If the prefix isn't "m2" for the 2013 namespace, Visual Studio Update 2 won't open the document in the designer view. Even though there is nothing technically wrong with the way it's currently done, change it to "m2" to keep VS happy. Change-Id: I62721114610de5396eb507828b39db89c1e96b1a Reviewed-by: Oliver Wolff --- .../winrt_winphone/manifests/8.1/AppxManifest.xml.in | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in index 5587ace390..97d3407403 100644 --- a/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in +++ b/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in @@ -1,5 +1,5 @@ - + - - - - - - - - + + + + + + + $${WINRT_MANIFEST.capabilities}$${WINRT_MANIFEST.dependencies} -- cgit v1.2.3 From 3438fb961a38bb14292bdd7f10e2efd164cd9ab6 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Thu, 22 May 2014 16:49:43 +0300 Subject: Fall back to ANGLE BlitFramebuffer and RenderbufferStorageMultiSample When these extensions aren't available, use ANGLE's versions of them. Task-number: QTBUG-31010 Change-Id: I9a85b9f4d2bb60bdb1d79c92edf241b95d0627bf Reviewed-by: Gunnar Sletta Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglfunctions.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index bcb38ce7f1..a0d1775040 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -381,6 +381,10 @@ static int qt_gl_resolve_extensions() // TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing. if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888")) extensions |= QOpenGLExtensions::BGRATextureFormat; + if (extensionMatcher.match("GL_ANGLE_framebuffer_blit")) + extensions |= QOpenGLExtensions::FramebufferBlit; + if (extensionMatcher.match("GL_ANGLE_framebuffer_multisample")) + extensions |= QOpenGLExtensions::FramebufferMultisample; } else { extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer; @@ -3150,7 +3154,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - RESOLVE_FUNC_VOID(ResolveEXT, BlitFramebuffer) + RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, BlitFramebuffer, BlitFramebufferANGLE) (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } @@ -3158,7 +3162,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLen GLenum internalFormat, GLsizei width, GLsizei height) { - RESOLVE_FUNC_VOID(ResolveEXT, RenderbufferStorageMultisample) + RESOLVE_FUNC_VOID_WITH_ALTERNATE(ResolveEXT, RenderbufferStorageMultisample, RenderbufferStorageMultisampleANGLE) (target, samples, internalFormat, width, height); } -- cgit v1.2.3 From 37fd82b9625db0aa90bb41f454956d3d84fa2573 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Thu, 22 May 2014 08:27:09 -0700 Subject: QPrintDialog OSX: Fix qApp->processEvents arguments The call to processEvents had the flags separated by a comma instead of bitwise OR. This worked because processEvents has an optional second argument that is an int. Change-Id: I6dc74bc44b1d782aa7206f106c51c16eab5f2a76 Reviewed-by: Jake Petroules --- src/printsupport/dialogs/qprintdialog_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index ef3e88be39..ba3837d497 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -239,7 +239,7 @@ void QPrintDialogPrivate::openCocoaPrintPanel(Qt::WindowModality modality) // Call processEvents in case the event dispatcher has been interrupted, and needs to do // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // close down during the cleanup (QTBUG-17913): - qApp->processEvents(QEventLoop::ExcludeUserInputEvents, QEventLoop::ExcludeSocketNotifiers); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) alloc] initWithNSPrintInfo:printInfo]; if (modality == Qt::ApplicationModal || !q->parentWidget()) { -- cgit v1.2.3 From a591c272820c623e3bfcf0aea39209f4a03d341d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 22 May 2014 16:37:49 +0200 Subject: Stabilize and speed up tst_QGraphicsItem::cursor(). Use QTRY_COMPARE instead of hard-coded timeouts, ensure window is shown. Change-Id: I4f23144ee14150c4fba9c6fbd8c4ee2da472cc75 Reviewed-by: Robin Burchell --- .../qgraphicsitem/tst_qgraphicsitem.cpp | 34 ++++++++++++++-------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 84466b92d1..e9aae1ec59 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +142,17 @@ static void sendKeyClick(QGraphicsScene *scene, Qt::Key key) sendKeyRelease(scene, key); } +static inline void centerOnScreen(QWidget *w, const QSize &size) +{ + const QPoint offset = QPoint(size.width() / 2, size.height() / 2); + w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); +} + +static inline void centerOnScreen(QWidget *w) +{ + centerOnScreen(w, w->geometry().size()); +} + class EventSpy : public QGraphicsWidget { Q_OBJECT @@ -4211,14 +4223,18 @@ void tst_QGraphicsItem::cursor() item2->setCursor(Qt::PointingHandCursor); QWidget topLevel; + topLevel.resize(250, 150); + centerOnScreen(&topLevel); QGraphicsView view(&scene,&topLevel); view.setFixedSize(200, 100); topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QTest::mouseMove(&view, view.rect().center()); QTest::qWait(25); - QCursor cursor = view.viewport()->cursor(); + const Qt::CursorShape viewportShape = view.viewport()->cursor().shape(); { QTest::mouseMove(view.viewport(), QPoint(100, 50)); @@ -4226,9 +4242,7 @@ void tst_QGraphicsItem::cursor() QApplication::sendEvent(view.viewport(), &event); } - QTest::qWait(25); - - QCOMPARE(view.viewport()->cursor().shape(), cursor.shape()); + QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); { QTest::mouseMove(view.viewport(), view.mapFromScene(item1->sceneBoundingRect().center())); @@ -4236,7 +4250,7 @@ void tst_QGraphicsItem::cursor() QApplication::sendEvent(view.viewport(), &event); } - QCOMPARE(view.viewport()->cursor().shape(), item1->cursor().shape()); + QTRY_COMPARE(view.viewport()->cursor().shape(), item1->cursor().shape()); { QTest::mouseMove(view.viewport(), view.mapFromScene(item2->sceneBoundingRect().center())); @@ -4244,9 +4258,7 @@ void tst_QGraphicsItem::cursor() QApplication::sendEvent(view.viewport(), &event); } - QTest::qWait(25); - - QCOMPARE(view.viewport()->cursor().shape(), item2->cursor().shape()); + QTRY_COMPARE(view.viewport()->cursor().shape(), item2->cursor().shape()); { QTest::mouseMove(view.viewport(), view.rect().center()); @@ -4254,9 +4266,7 @@ void tst_QGraphicsItem::cursor() QApplication::sendEvent(view.viewport(), &event); } - QTest::qWait(25); - - QCOMPARE(view.viewport()->cursor().shape(), cursor.shape()); + QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); } #endif /* -- cgit v1.2.3 From 390a8c36f7a59db4c3fe92d0c28ef084ebb92954 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 20 May 2014 15:04:35 +0900 Subject: Fix a crash in QOpenGLTexture::allocateStorage() QOpenGLTexture texture(QOpenGLTexture::Target2D); texture.allocateStorage(); // crashed Change-Id: Ia12f69b72e537cf765387cd172d7cb2cbbbad6e6 Reviewed-by: Gunnar Sletta Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltexture.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index e3444332a0..6b6d4bcf41 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2081,7 +2081,9 @@ int QOpenGLTexture::faces() const void QOpenGLTexture::allocateStorage() { Q_D(QOpenGLTexture); - d->allocateStorage(); + if (d->create()) { + d->allocateStorage(); + } } /*! -- cgit v1.2.3 From 9f4881297d961646bf3d02593045b8a1ce7670e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 22 May 2014 09:33:37 +0300 Subject: Mark tst_qfiledialog2 as insignificant due to failing tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-39183 Change-Id: I6663d0e4c49e904ffe5d5fdc990073abd4188d9d Reviewed-by: Simo Fält --- tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro index db36eea11d..5239614fc7 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro +++ b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro @@ -19,3 +19,5 @@ wince* { } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" } + +macx:CONFIG += insignificant_test # QTBUG-39183 -- cgit v1.2.3 From 0057507184bc87fc26be95298d8d734a47e73251 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Fri, 23 May 2014 08:01:43 +0300 Subject: Direct2D QPA: Add missing break statement Change-Id: Ib40daa1ba56cce423b29ac8f1ab50e4638980728 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 3b598b365d..e3adcde964 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -469,6 +469,7 @@ public: break; case Qt::RoundCap: props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_ROUND; + break; case Qt::FlatCap: default: props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT; -- cgit v1.2.3 From c6b877917241257d159bd3b9070c4be09231f40b Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Thu, 22 May 2014 10:12:39 +0300 Subject: Direct2D QPA: Fix HighRes painting It turns out that supporting HighRes painting with Direct2D is quite simple. Two things are necessary. First, we set the unit mode to D2D1_UNIT_MODE_PIXELS on all our device contexts, which tells Direct2D that we specify everything in pixels. Direct2D will internally do the required conversions. Second, we scale font sizes according to DPI. Previously rendering errors resulted when a highres mode was used, this fixes those errors. Task-number: QTBUG-39105 Change-Id: Ibb4dbea4746687228249e2c36d48c4bd6c5c7bf9 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2ddevicecontext.cpp | 1 + .../direct2d/qwindowsdirect2dpaintengine.cpp | 20 +++++++++----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp index fb47851a06..f2400cf8fc 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp @@ -64,6 +64,7 @@ public: } Q_ASSERT(deviceContext); + deviceContext->SetUnitMode(D2D1_UNIT_MODE_PIXELS); } void begin() diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index e3adcde964..a1c405067c 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -1465,29 +1465,27 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem rtl); } -// Points (1/72 inches) to Microsoft's Device Independent Pixels (1/96 inches) -inline static Q_DECL_CONSTEXPR FLOAT pointSizeToDIP(qreal pointSize) +inline static FLOAT pointSizeToDIP(qreal pointSize, FLOAT dpiY) { - return pointSize + (pointSize / qreal(3.0)); + return (pointSize + (pointSize / qreal(3.0))) * (dpiY / 96.0f); } -inline static FLOAT pixelSizeToDIP(int pixelSize) +inline static FLOAT pixelSizeToDIP(int pixelSize, FLOAT dpiY) { - FLOAT dpiX, dpiY; - factory()->GetDesktopDpi(&dpiX, &dpiY); - - return FLOAT(pixelSize) / (dpiY / 96.0f); + return FLOAT(pixelSize) * 96.0f / dpiY; } inline static FLOAT fontSizeInDIP(const QFont &font) { - // Direct2d wants the font size in DIPs (Device Independent Pixels), each of which is 1/96 inches. + FLOAT dpiX, dpiY; + QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&dpiX, &dpiY); + if (font.pixelSize() == -1) { // font size was set as points - return pointSizeToDIP(font.pointSizeF()); + return pointSizeToDIP(font.pointSizeF(), dpiY); } else { // font size was set as pixels - return pixelSizeToDIP(font.pixelSize()); + return pixelSizeToDIP(font.pixelSize(), dpiY); } } -- cgit v1.2.3 From 05e8b54d23e3d906d5f29113a73d88d3482c8f64 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Thu, 22 May 2014 17:08:45 +0300 Subject: WinRT: fix default font when DirectWrite is disabled Instead of loading the default font "Helvetica", which is likely not part of the package, load the first font found. Change-Id: I225979986883a26c3fec72858cf32c3d1e45d902 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtfontdatabase.cpp | 9 ++++++++- src/plugins/platforms/winrt/qwinrtfontdatabase.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 7de223bbed..f4e1fbe533 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp @@ -398,6 +398,13 @@ void QWinRTFontDatabase::releaseHandle(void *handle) QBasicFontDatabase::releaseHandle(handle); } -#endif // QT_WINRT_USE_DWRITE +#else // QT_WINRT_USE_DWRITE + +QFont QWinRTFontDatabase::defaultFont() const +{ + return QFont(QFontDatabase().families().value(0)); +} + +#endif // !QT_WINRT_USE_DWRITE QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h index 19bf6fa9cf..eabcc83afd 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h @@ -61,9 +61,9 @@ class QWinRTFontDatabase : public QBasicFontDatabase { public: QString fontDir() const; + QFont defaultFont() const Q_DECL_OVERRIDE; #ifdef QT_WINRT_USE_DWRITE ~QWinRTFontDatabase(); - QFont defaultFont() const Q_DECL_OVERRIDE; void populateFontDatabase() Q_DECL_OVERRIDE; void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE; -- cgit v1.2.3 From 26985092190a80c2db463f42c082c9f4792b5e66 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 22 May 2014 13:38:17 +0200 Subject: Call doneCurrent on QOpenGLContext when the surface dies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doing makeCurrent() followed by destroying the surface (and no doneCurrent) results in still having the pointer stored internally in the QOpenGLContext. If then a function like defaultFramebufferObject() is called, the pointer is dereferenced. To fix this, the doneCurrent() has to be called when the surface is destroyed before the context without doneCurrent(). This is pretty much what the user would expect anyhow. Task-number: QTBUG-38994 Change-Id: Ibd4083d9291c7fd39b38ce81a988a8e0c9d55d60 Reviewed-by: Friedemann Kleint Reviewed-by: Jørgen Lind --- src/gui/kernel/qsurface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp index a27bdaccde..e7fd2f79a4 100644 --- a/src/gui/kernel/qsurface.cpp +++ b/src/gui/kernel/qsurface.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qsurface.h" +#include "qopenglcontext.h" QT_BEGIN_NAMESPACE @@ -130,6 +131,11 @@ QSurface::QSurface(SurfaceClass type) */ QSurface::~QSurface() { +#ifndef QT_NO_OPENGL + QOpenGLContext *context = QOpenGLContext::currentContext(); + if (context && context->surface() == this) + context->doneCurrent(); +#endif } /*! -- cgit v1.2.3 From 4a35f21208f2f6ae23a4a2f668c72ea6d9def4c9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 21 May 2014 15:14:45 +0200 Subject: fix quoting and path separators in qtPrepareTool() we need to store commands with system path separators in the .pri files, as we might clobber windows command arguments if we just converted separators later on. and we can actually do that, as the path separators are actually bound to the host system, not the shell. we also need to shell-quote the commands, as whitespace, and more commonly windows path separators in an msys shell, would break things. we delay this to the last moment possible, as it does depend on the shell. Change-Id: I1fe6b63aebd5663b72492c32928ec397f86e336f Reviewed-by: Sergio Ahumada --- mkspecs/features/qt_functions.prf | 24 ++++++++++++++---------- mkspecs/features/qt_tool.prf | 3 ++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 64b9fee361..d41fe3b4d5 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -191,26 +191,30 @@ defineTest(qtAddRpathLink) { # variable, default, [suffix for variable for system() use] defineTest(qtPrepareTool) { - $$1 = $$eval(QT_TOOL.$${2}.binary) - isEmpty($$1) { - $$1 = $$[QT_HOST_BINS]/$$2 - exists($$eval($$1).pl) { - $$1 = perl -w $$eval($$1).pl + cmd = $$eval(QT_TOOL.$${2}.binary) + isEmpty(cmd) { + cmd = $$[QT_HOST_BINS]/$$2 + exists($${cmd}.pl) { + cmd = perl -w $$system_path($${cmd}.pl) } else: contains(QMAKE_HOST.os, Windows) { - $$1 = $$eval($$1).exe + cmd = $$system_path($${cmd}.exe) } else:contains(QMAKE_HOST.os, Darwin) { - BUNDLENAME = $$eval($$1).app/Contents/MacOS/$$2 + BUNDLENAME = $${cmd}.app/Contents/MacOS/$$2 exists($$BUNDLENAME) { - $$1 = $$BUNDLENAME + cmd = $$BUNDLENAME } } } QT_TOOL_ENV += $$eval(QT_TOOL.$${2}.envvars) !isEmpty(3) { - $$1$$3 = $$system_path($$eval($$1)) + $$1$$3 = + for (arg, cmd): \ + $$1$$3 += $$system_quote($$arg) qtAddTargetEnv($$1$$3, QT_TOOL.$${2}.depends, system) } - $$1 = $$system_path($$eval($$1)) + $$1 = + for (arg, cmd): \ + $$1 += $$shell_quote($$arg) qtAddTargetEnv($$1, QT_TOOL.$${2}.depends, ) } diff --git a/mkspecs/features/qt_tool.prf b/mkspecs/features/qt_tool.prf index f0864f9e74..1d3e88cbe9 100644 --- a/mkspecs/features/qt_tool.prf +++ b/mkspecs/features/qt_tool.prf @@ -45,8 +45,9 @@ CONFIG += console } else { module_envvars = } + bin = $$system_path($$QMAKE_RESOLVED_TARGET) TOOL_PRI_CONT = \ - "QT_TOOL.$${MODULE}.binary = $$QMAKE_RESOLVED_TARGET" \ + "QT_TOOL.$${MODULE}.binary = $$val_escape(bin)" \ "QT_TOOL.$${MODULE}.depends =$$join(MODULE_DEPENDS, " ", " ")" \ $$module_envvars write_file($$TOOL_PRI, TOOL_PRI_CONT)|error("Aborting.") -- cgit v1.2.3 From 7c94b8955f5c0e0fe0633f2a4ddfd0c050e02f62 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 21 May 2014 14:14:05 +0200 Subject: purge obsolete variable documentationPath Change-Id: I1eb9e7ff28e0632c5a87b726dcd52b6542612101 Reviewed-by: Martin Smith --- src/tools/qdoc/main.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 3d2ee409b0..2c1c28ec8c 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -84,7 +84,6 @@ static QStringList dependModules; static QStringList indexDirs; static QString currentDir; static QString prevCurrentDir; -static QString documentationPath; /*! Print the help message to \c stdout. @@ -155,11 +154,6 @@ static void loadIndexFiles(Config& config) singleOutputSubdir = "html"; } - // Allow modules and third-party application/libraries to link - // to the Qt docs without having to explicitly pass --indexdir. - if (!indexDirs.contains(documentationPath)) - indexDirs.append(documentationPath); - if (dependModules.size() > 0) { if (indexDirs.size() > 0) { for (int i = 0; i < indexDirs.size(); i++) { -- cgit v1.2.3 From a658fa40d3c4d61ac3c655df9f57630a26192d74 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 12 May 2014 15:23:27 +0200 Subject: fix/simplify the qmlimportscanner's import path construction now that we have QTREPOS, we can use that directly instead of collecting the QT..qml dirs. as a "side effect", this makes qml modules without a corresponding c++ module available to the scan. Change-Id: I6f172121588ec01c9fa47a99d9990bf9fcfbc69f Reviewed-by: Joerg Bornemann --- mkspecs/features/qt.prf | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 54423017ee..c3395d09ac 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -82,13 +82,9 @@ contains(qt_module_deps, qml): \ contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { # run qmlimportscanner qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner) - for (MODULE, QT_MODULES) { - PATH = $$eval(QT.$${MODULE}.qml) - !isEmpty(PATH):exists($$PATH): QMLPATHS += $$PATH - } - QMLPATHS = $$unique(QMLPATHS) - for (QMLPATH, QMLPATHS): \ - IMPORTPATHS += -importPath $$QMLPATH + for (qrep, QTREPOS): \ + exists($$qrep/qml): \ + IMPORTPATHS += -importPath $$qrep/qml #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) -- cgit v1.2.3 From 3b7599800e3c0185f5a5632460eb830103945062 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 12 May 2014 15:24:45 +0200 Subject: fix qmlplugindump's import path construction the location of the import paths have changed a long time ago. also, we can make use of QTREPOS now. Change-Id: Iee50854b7441968c3c60538e54d9312e53d39cb6 Reviewed-by: Joerg Bornemann --- mkspecs/features/qml_plugin.prf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index f161a71ef9..ad55b889ac 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -81,9 +81,11 @@ load(qt_common) qmlplugindump = qmlplugindump qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump) importpath.value = - for(qmod, QMAKEMODULES) { - qmod = $$section(qmod, /, 0, -3)/imports - qml1_target: qmod = $$qmod/QtDeclarative + for(qmod, QTREPOS) { + qml1_target: \ + qmod = $$qmod/imports + else: \ + qmod = $$qmod/qml exists($$qmod): importpath.value += $$shell_path($$qmod) } importpath.name = QML_IMPORT_PATH -- cgit v1.2.3 From a12a2fdf684a6fc19aefc14f32842deab0270e86 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 22 May 2014 14:31:25 +0200 Subject: fix C4275 warnings for MSVC 2010 build The _HAS_EXCEPTIONS=0 define that was introduced in commit f59083636b89fc9b7983f9a0758a79f2980826dc leads to lots of C4275 warnings: non dll-interface class "stdext::exception" used as base for dll-interface class "std::bad_cast" from the include in qglobal.h. Newer versions of MSVC do not have this problem. Task-number: QTBUG-39126 Change-Id: Ieea5adde649fe16e6b41fbbb23fd582b3bb12b89 Reviewed-by: Friedemann Kleint --- mkspecs/win32-msvc2010/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/win32-msvc2010/qmake.conf b/mkspecs/win32-msvc2010/qmake.conf index f24da2d5c6..54286d51c2 100644 --- a/mkspecs/win32-msvc2010/qmake.conf +++ b/mkspecs/win32-msvc2010/qmake.conf @@ -54,7 +54,7 @@ QMAKE_CXXFLAGS_STL_OFF = QMAKE_CXXFLAGS_RTTI_ON = -GR QMAKE_CXXFLAGS_RTTI_OFF = QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc -QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0 +QMAKE_CXXFLAGS_EXCEPTIONS_OFF = QMAKE_INCDIR = -- cgit v1.2.3 From 8f8d3aa4e8947cdfc3e04cd5cd62eee152cbbcd2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 22 May 2014 10:46:52 +0200 Subject: escape apostrophe Change-Id: Ib9da4903167fce8ccc41fd2aa050b5c611cced11 Reviewed-by: Stephen Kelly --- src/gui/Qt5GuiConfigExtras.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in index f9c327f938..d734e56d23 100644 --- a/src/gui/Qt5GuiConfigExtras.cmake.in +++ b/src/gui/Qt5GuiConfigExtras.cmake.in @@ -107,7 +107,7 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs) set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}") !!ENDIF if (WIN32 AND NOT Qt5Gui_${_cmake_lib_name}_LIBRARY) - # The above find_library call doesn't work for finding + # The above find_library call doesn\'t work for finding # libraries in Windows SDK paths outside of the proper # environment. Just add the library name to the result # variable instead. -- cgit v1.2.3 From cf4d0a64e9909ff3c989a77f5d297dadc76e58e2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 7 May 2014 14:22:30 +0200 Subject: fix and de-duplicate qprocess apidocs - rectify confusion and outright disinformation about argument quoting - say that open() is an alias for start(), not the other way round, as this is more consistent - apply some trickery to hide mergeable startDetached() overload - rename program -> command where it stands for a joined command line, for consistency - copy less information to the various overloads - misc language fixes and reshuffling Change-Id: I1b9c8dbed003f551ee6855044bbfc0aedddb4757 Reviewed-by: Thiago Macieira Reviewed-by: Jerome Pasion --- .../doc/snippets/code/src_corelib_io_qprocess.cpp | 2 +- src/corelib/io/qprocess.cpp | 137 ++++++++++----------- src/corelib/io/qprocess.h | 16 ++- 3 files changed, 77 insertions(+), 78 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qprocess.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qprocess.cpp index b5d71079da..e9c3caae5b 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qprocess.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qprocess.cpp @@ -121,7 +121,7 @@ process.start("dir \"My Documents\""); //! [7] QProcess process; -process.start("dir \"\"\"My Documents\"\"\""); +process.start("dir \"Epic 12\"\"\" Singles\""); //! [7] diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 18391703da..9f9cba81ab 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -2015,15 +2015,12 @@ QByteArray QProcess::readAllStandardError() } /*! - Starts the given \a program in a new process, if none is already - running, passing the command line arguments in \a arguments. The OpenMode - is set to \a mode. + Starts the given \a program in a new process, passing the command line + arguments in \a arguments. The QProcess object will immediately enter the Starting state. If the process starts successfully, QProcess will emit started(); otherwise, - error() will be emitted. If the QProcess object is already running a - process, a warning may be printed at the console, and the existing - process will continue running. + error() will be emitted. \note Processes are started asynchronously, which means the started() and error() signals may be delayed. Call waitForStarted() to make @@ -2032,9 +2029,18 @@ QByteArray QProcess::readAllStandardError() \note No further splitting of the arguments is performed. - \b{Windows:} Arguments that contain spaces are wrapped in quotes. + \b{Windows:} The arguments are quoted and joined into a command line + that is compatible with the CommandLineToArgvW() Windows function. + For programs that have different command line quoting requirements, + you need to use setNativeArguments(). - \sa pid(), started(), waitForStarted() + The OpenMode is set to \a mode. + + If the QProcess object is already running a process, a warning may be + printed at the console, and the existing process will continue running + unaffected. + + \sa pid(), started(), waitForStarted(), setNativeArguments() */ void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode) { @@ -2057,8 +2063,6 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM Starts the program set by setProgram() with arguments set by setArguments(). The OpenMode is set to \a mode. - This method is a convenient alias to open(). - \sa open(), setProgram(), setArguments() */ void QProcess::start(OpenMode mode) @@ -2077,22 +2081,13 @@ void QProcess::start(OpenMode mode) } /*! - Starts the program set by setProgram() in a new process, if none is already - running, passing the command line arguments set by setArguments(). The OpenMode - is set to \a mode. - - The QProcess object will immediately enter the Starting state. If the - process starts successfully, QProcess will emit started(); otherwise, - error() will be emitted. If the QProcess object is already running a - process, a warning may be printed at the console, the function will return false, - and the existing process will continue running. + Starts the program set by setProgram() with arguments set by setArguments(). + The OpenMode is set to \a mode. - \note Processes are started asynchronously, which means the started() - and error() signals may be delayed. Call waitForStarted() to make - sure the process has started (or has failed to start) and those signals - have been emitted. In this regard, a true return value merly means the process - was correcty initialized, not that the program was actually started. + This method is an alias for start(), and exists only to fully implement + the interface defined by QIODevice. + \sa start(), setProgram(), setArguments() */ bool QProcess::open(OpenMode mode) { @@ -2185,29 +2180,28 @@ static QStringList parseCombinedArgString(const QString &program) /*! \overload - Starts the command \a command in a new process, if one is not already - running. \a command is a single string of text containing both the - program name and its arguments. The arguments are separated by one or - more spaces. For example: + Starts the command \a command in a new process. + The OpenMode is set to \a mode. + + \a command is a single string of text containing both the program name + and its arguments. The arguments are separated by one or more spaces. + For example: \snippet code/src_corelib_io_qprocess.cpp 5 - The \a command string can also contain quotes, to ensure that arguments - containing spaces are correctly supplied to the new process. For example: + Arguments containing spaces must be quoted to be correctly supplied to + the new process. For example: \snippet code/src_corelib_io_qprocess.cpp 6 - If the QProcess object is already running a process, a warning may be - printed at the console, and the existing process will continue running. - - Note that, on Windows, quotes need to be both escaped and quoted. - For example, the above code would be specified in the following - way to ensure that \c{"My Documents"} is used as the argument to - the \c dir executable: + Literal quotes in the \a command string are represented by triple quotes. + For example: \snippet code/src_corelib_io_qprocess.cpp 7 - The OpenMode is set to \a mode. + After the \a command string has been split and unquoted, this function + behaves like the overload which takes the arguments as a string list. + */ void QProcess::start(const QString &command, OpenMode mode) { @@ -2243,7 +2237,7 @@ QString QProcess::program() const \since 5.1 Set the \a program to use when starting the process. - That function must be call before open() + This function must be called before start(). \sa start(), setArguments(), program() */ @@ -2274,7 +2268,7 @@ QStringList QProcess::arguments() const \since 5.1 Set the \a arguments to pass to the called program when starting the process. - That function must be call before open() + This function must be called before start(). \sa start(), setProgram(), arguments() */ @@ -2359,11 +2353,13 @@ QProcess::ExitStatus QProcess::exitStatus() const The environment and working directory are inherited from the calling process. - On Windows, arguments that contain spaces are wrapped in quotes. + Argument handling is identical to the respective start() overload. If the process cannot be started, -2 is returned. If the process crashes, -1 is returned. Otherwise, the process' exit code is returned. + + \sa start() */ int QProcess::execute(const QString &program, const QStringList &arguments) { @@ -2378,15 +2374,21 @@ int QProcess::execute(const QString &program, const QStringList &arguments) /*! \overload - Starts the program \a program in a new process. \a program is a - single string of text containing both the program name and its - arguments. The arguments are separated by one or more spaces. + Starts the program \a command in a new process, waits for it to finish, + and then returns the exit code. + + Argument handling is identical to the respective start() overload. + + After the \a command string has been split and unquoted, this function + behaves like the overload which takes the arguments as a string list. + + \sa start() */ -int QProcess::execute(const QString &program) +int QProcess::execute(const QString &command) { QProcess process; process.setReadChannelMode(ForwardedChannels); - process.start(program); + process.start(command); if (!process.waitForFinished(-1)) return -2; return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1; @@ -2396,24 +2398,24 @@ int QProcess::execute(const QString &program) Starts the program \a program with the arguments \a arguments in a new process, and detaches from it. Returns \c true on success; otherwise returns \c false. If the calling process exits, the - detached process will continue to live. + detached process will continue to run unaffected. - Note that arguments that contain spaces are not passed to the - process as separate arguments. + Argument handling is identical to the respective start() overload. \b{Unix:} The started process will run in its own session and act like a daemon. - \b{Windows:} Arguments that contain spaces are wrapped in quotes. - The started process will run as a regular standalone process. - The process will be started in the directory \a workingDirectory. + If \a workingDirectory is empty, the working directory is inherited + from the calling process. \note On QNX, this may cause all application threads to temporarily freeze. If the function is successful then *\a pid is set to the process identifier of the started process. + + \sa start() */ bool QProcess::startDetached(const QString &program, const QStringList &arguments, @@ -2427,19 +2429,7 @@ bool QProcess::startDetached(const QString &program, } /*! - Starts the program \a program with the given \a arguments in a - new process, and detaches from it. Returns \c true on success; - otherwise returns \c false. If the calling process exits, the - detached process will continue to live. - - \note Arguments that contain spaces are not passed to the - process as separate arguments. - - \b{Unix:} The started process will run in its own session and act - like a daemon. - - \b{Windows:} Arguments that contain spaces are wrapped in quotes. - The started process will run as a regular standalone process. + \internal */ bool QProcess::startDetached(const QString &program, const QStringList &arguments) @@ -2450,16 +2440,19 @@ bool QProcess::startDetached(const QString &program, /*! \overload - Starts the program \a program in a new process. \a program is a - single string of text containing both the program name and its - arguments. The arguments are separated by one or more spaces. + Starts the command \a command in a new process, and detaches from it. + Returns \c true on success; otherwise returns \c false. + + Argument handling is identical to the respective start() overload. + + After the \a command string has been split and unquoted, this function + behaves like the overload which takes the arguments as a string list. - The \a program string can also contain quotes, to ensure that arguments - containing spaces are correctly supplied to the new process. + \sa start() */ -bool QProcess::startDetached(const QString &program) +bool QProcess::startDetached(const QString &command) { - QStringList args = parseCombinedArgString(program); + QStringList args = parseCombinedArgString(command); if (args.isEmpty()) return false; diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 6be267f15f..94359acf00 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -209,12 +209,18 @@ public: bool atEnd() const; static int execute(const QString &program, const QStringList &arguments); - static int execute(const QString &program); + static int execute(const QString &command); - static bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, - qint64 *pid = 0); - static bool startDetached(const QString &program, const QStringList &arguments); - static bool startDetached(const QString &program); + static bool startDetached(const QString &program, const QStringList &arguments, + const QString &workingDirectory +#if defined(Q_QDOC) + = QString() +#endif + , qint64 *pid = 0); +#if !defined(Q_QDOC) + static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads +#endif + static bool startDetached(const QString &command); static QStringList systemEnvironment(); -- cgit v1.2.3 From 28f32afd3fed07c7772b76faf731bb104810d934 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 23 May 2014 10:51:19 +0200 Subject: iOS: Be more careful when hiding the keyboard upon enter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A typical pattern in an application is to listen for "enter" in a line edit and transfer focus to the next edit in the focus chain. This would currently not work on iOS since we would force the keyboard down after delivering the KeyPress/release events, effectively overriding any focus handling done by the app. This patch will hide the keyboard _before_ sending the events, so that we don't override focus handling done by the app. By also hiding the keyboard using QInputMethod, the hiding will also be delayed a bit (in QIOSInputContext) to catch subsequent hide/show calls. Change-Id: Ic19511d494a55d1bda963ed9bc7185d63b51bc03 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview_textinput.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm index 79e3897013..03006b3f99 100644 --- a/src/plugins/platforms/ios/quiview_textinput.mm +++ b/src/plugins/platforms/ios/quiview_textinput.mm @@ -495,14 +495,14 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables); return; if ([text isEqualToString:@"\n"]) { + if (self.returnKeyType == UIReturnKeyDone) + qApp->inputMethod()->hide(); + QKeyEvent press(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); QKeyEvent release(QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier); [self sendEventToFocusObject:press]; [self sendEventToFocusObject:release]; - if (self.returnKeyType == UIReturnKeyDone) - [self resignFirstResponder]; - return; } -- cgit v1.2.3 From 57d0ed8f1e0b2e98102bd3718abd449d5dd7aa1d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 May 2014 11:28:06 +0200 Subject: Remove unused variable in qwindowsmousehandler.cpp. Change-Id: Iacfeec396c2eeef973b62bf78c698aa206b01c41 Reviewed-by: Andy Shaw --- src/plugins/platforms/windows/qwindowsmousehandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 5c9add4baa..cc0597b72d 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -354,7 +354,6 @@ static bool isValidWheelReceiver(QWindow *candidate) bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND, MSG msg, LRESULT *) { - const Qt::MouseButtons buttons = keyStateToMouseButtons((int)msg.wParam); const Qt::KeyboardModifiers mods = keyStateToModifiers((int)msg.wParam); int delta; -- cgit v1.2.3 From d3d8ade87b74c541cc3baa67b9972d6471864c25 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 20 May 2014 14:44:26 +0200 Subject: Windows: Fix qt_imageFromWinHBITMAP(). Factor out common code paths from the QPixmap/QImage conversion code and use the same algorithm for copying the image data with alpha correction as does qt_pixmapFromWinHBITMAP(). Rename the previous version of qt_imageFromWinHBITMAP() to qt_imageFromWinIconHBITMAP() since it is used for HICON conversion. Task-number: QTBUG-39084 Change-Id: Ia4042c33db485c3604461a5eafd6282968b36e3b Reviewed-by: Andy Shaw --- src/gui/image/qpixmap_win.cpp | 160 +++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 74 deletions(-) diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 93efe2e696..6cbb6fdb69 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -133,6 +133,68 @@ int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID l } #endif +static inline void initBitMapInfoHeader(int width, int height, bool topToBottom, BITMAPINFOHEADER *bih) +{ + memset(bih, 0, sizeof(BITMAPINFOHEADER)); + bih->biSize = sizeof(BITMAPINFOHEADER); + bih->biWidth = width; + bih->biHeight = topToBottom ? -height : height; + bih->biPlanes = 1; + bih->biBitCount = 32; + bih->biCompression = BI_RGB; + bih->biSizeImage = width * height * 4; +} + +static inline void initBitMapInfo(int width, int height, bool topToBottom, BITMAPINFO *bmi) +{ + initBitMapInfoHeader(width, height, topToBottom, &bmi->bmiHeader); + memset(bmi->bmiColors, 0, sizeof(RGBQUAD)); +} + +static inline uchar *getDiBits(HDC hdc, HBITMAP bitmap, int width, int height, bool topToBottom = true) +{ + BITMAPINFO bmi; + initBitMapInfo(width, height, topToBottom, &bmi); + uchar *result = new uchar[bmi.bmiHeader.biSizeImage]; + if (!GetDIBits(hdc, bitmap, 0, height, result, &bmi, DIB_RGB_COLORS)) { + delete [] result; + qErrnoWarning("%s: GetDIBits() failed to get bitmap bits.", __FUNCTION__); + return 0; + } + return result; +} + +static inline void copyImageDataCreateAlpha(const uchar *data, QImage *target) +{ + const uint mask = target->format() == QImage::Format_RGB32 ? 0xff000000 : 0; + const int height = target->height(); + const int width = target->width(); + const int bytesPerLine = width * int(sizeof(QRgb)); + for (int y = 0; y < height; ++y) { + QRgb *dest = reinterpret_cast(target->scanLine(y)); + const QRgb *src = reinterpret_cast(data + y * bytesPerLine); + for (int x = 0; x < width; ++x) { + const uint pixel = src[x]; + if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0) + dest[x] = pixel | 0xff000000; + else + dest[x] = pixel | mask; + } + } +} + +static inline void copyImageData(const uchar *data, QImage *target) +{ + const int height = target->height(); + const int bytesPerLine = target->bytesPerLine(); + for (int y = 0; y < height; ++y) { + void *dest = static_cast(target->scanLine(y)); + const void *src = data + y * bytesPerLine; + memcpy(dest, src, bytesPerLine); + } + +} + enum HBitmapFormat { HBitmapNoAlpha, @@ -176,14 +238,7 @@ Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = // Define the header BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; + initBitMapInfo(w, h, true, &bmi); // Create the pixmap uchar *pixels = 0; @@ -227,31 +282,16 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = const int w = bitmap_info.bmWidth; const int h = bitmap_info.bmHeight; - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - // Get bitmap bits - QScopedArrayPointer data(new uchar[bmi.bmiHeader.biSizeImage]); HDC display_dc = GetDC(0); - if (!GetDIBits(display_dc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) { + QScopedArrayPointer data(getDiBits(display_dc, bitmap, w, h, true)); + if (data.isNull()) { ReleaseDC(0, display_dc); - qWarning("%s, failed to get bitmap bits", __FUNCTION__); return QPixmap(); } - QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied; - uint mask = 0; - if (hbitmapFormat == HBitmapNoAlpha) { - imageFormat = QImage::Format_RGB32; - mask = 0xff000000; - } + const QImage::Format imageFormat = hbitmapFormat == HBitmapNoAlpha ? + QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied; // Create image and copy data into image. QImage image(w, h, imageFormat); @@ -260,18 +300,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = qWarning("%s, failed create image of %dx%d", __FUNCTION__, w, h); return QPixmap(); } - const int bytes_per_line = w * sizeof(QRgb); - for (int y = 0; y < h; ++y) { - QRgb *dest = (QRgb *) image.scanLine(y); - const QRgb *src = (const QRgb *) (data.data() + y * bytes_per_line); - for (int x = 0; x < w; ++x) { - const uint pixel = src[x]; - if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0) - dest[x] = pixel | 0xff000000; - else - dest[x] = pixel | mask; - } - } + copyImageDataCreateAlpha(data.data(), &image); ReleaseDC(0, display_dc); return QPixmap::fromImage(image); } @@ -307,32 +336,25 @@ Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p) Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) { - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = w * h * 4; - QImage image(w, h, QImage::Format_ARGB32_Premultiplied); if (image.isNull()) return image; + QScopedArrayPointer data(getDiBits(hdc, bitmap, w, h, true)); + if (data.isNull()) + return QImage(); + copyImageDataCreateAlpha(data.data(), &image); + return image; +} - // Get bitmap bits - QScopedArrayPointer data(new uchar [bmi.bmiHeader.biSizeImage]); - if (!GetDIBits(hdc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) { - qErrnoWarning("%s: failed to get bitmap bits", __FUNCTION__); +static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h) +{ + QImage image(w, h, QImage::Format_ARGB32_Premultiplied); + if (image.isNull()) + return image; + QScopedArrayPointer data(getDiBits(hdc, bitmap, w, h, true)); + if (data.isNull()) return QImage(); - } - // Create image and copy data into image. - for (int y = 0; y < h; ++y) { - void *dest = (void *) image.scanLine(y); - void *src = data.data() + y * image.bytesPerLine(); - memcpy(dest, src, image.bytesPerLine()); - } + copyImageData(data.data(), &image); return image; } @@ -354,23 +376,13 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) const int h = iconinfo.yHotspot * 2; BITMAPINFOHEADER bitmapInfo; - bitmapInfo.biSize = sizeof(BITMAPINFOHEADER); - bitmapInfo.biWidth = w; - bitmapInfo.biHeight = h; - bitmapInfo.biPlanes = 1; - bitmapInfo.biBitCount = 32; - bitmapInfo.biCompression = BI_RGB; - bitmapInfo.biSizeImage = 0; - bitmapInfo.biXPelsPerMeter = 0; - bitmapInfo.biYPelsPerMeter = 0; - bitmapInfo.biClrUsed = 0; - bitmapInfo.biClrImportant = 0; + initBitMapInfoHeader(w, h, false, &bitmapInfo); DWORD* bits; HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0); HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap); DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL); - QImage image = qt_imageFromWinHBITMAP(hdc, winBitmap, w, h); + QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h); for (int y = 0 ; y < h && !foundAlpha ; y++) { const QRgb *scanLine= reinterpret_cast(image.scanLine(y)); @@ -384,7 +396,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon) if (!foundAlpha) { //If no alpha was found, we use the mask to set alpha values DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK); - const QImage mask = qt_imageFromWinHBITMAP(hdc, winBitmap, w, h); + const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h); for (int y = 0 ; y < h ; y++){ QRgb *scanlineImage = reinterpret_cast(image.scanLine(y)); -- cgit v1.2.3 From 9a2dbcab7e820c63aac55ba08dc120a56986efac Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 13 May 2014 14:08:05 +0200 Subject: QPrinter/Windows: Fix handling of native paper source ids. On Windows, it is possible to pass native Windows paper source ids >= DMBIN_USER to QPrinter::setPaperSource() and they are listed by supportedPaperSources(). Task-number: QTBUG-38897 Task-number: QTBUG-38888 Change-Id: I8f1264e80ce5bdddd3873602200b24eabee00502 Reviewed-by: Lars Knoll Reviewed-by: Andy Shaw --- .../printsupport/windows/qwindowsprintdevice.cpp | 1 + src/printsupport/kernel/qprintengine_win.cpp | 48 ++++++++++++++-------- tests/manual/dialogs/printdialogpanel.cpp | 11 ++++- tests/manual/dialogs/printdialogpanel.ui | 18 ++++++-- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index 1b55937ec7..2c75ab7016 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -78,6 +78,7 @@ static QPrint::InputSlot paperBinToInputSlot(int windowsId, const QString &name) } slot.key = inputSlotMap[i].key; slot.id = inputSlotMap[i].id; + slot.windowsId = windowsId; return slot; } diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 52b67d162b..427af13edf 100644 --- a/src/printsupport/kernel/qprintengine_win.cpp +++ b/src/printsupport/kernel/qprintengine_win.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -972,6 +972,24 @@ void QWin32PrintEnginePrivate::doReinit() } } +static int indexOfId(const QList &inputSlots, QPrint::InputSlotId id) +{ + for (int i = 0; i < inputSlots.size(); ++i) { + if (inputSlots.at(i).id == id) + return i; + } + return -1; +} + +static int indexOfWindowsId(const QList &inputSlots, int windowsId) +{ + for (int i = 0; i < inputSlots.size(); ++i) { + if (inputSlots.at(i).windowsId == windowsId) + return i; + } + return -1; +} + void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) { Q_D(QWin32PrintEngine); @@ -1114,14 +1132,12 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & case PPK_PaperSource: { if (!d->devMode) break; - QPrint::InputSlotId inputSlotId = QPrint::InputSlotId(value.toInt()); - foreach (const QPrint::InputSlot &inputSlot, d->m_printDevice.supportedInputSlots()) { - if (inputSlot.id == inputSlotId) { - d->devMode->dmDefaultSource = inputSlot.windowsId; - d->doReinit(); - break; - } - } + const QList inputSlots = d->m_printDevice.supportedInputSlots(); + const int paperSource = value.toInt(); + const int index = paperSource >= DMBIN_USER ? + indexOfWindowsId(inputSlots, paperSource) : indexOfId(inputSlots, QPrint::InputSlotId(paperSource)); + d->devMode->dmDefaultSource = index >= 0 ? inputSlots.at(index).windowsId : DMBIN_AUTO; + d->doReinit(); break; } @@ -1337,12 +1353,12 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const if (!d->devMode) { value = d->m_printDevice.defaultInputSlot().id; } else { - value = QPrint::Auto; - foreach (const QPrint::InputSlot inputSlot, d->m_printDevice.supportedInputSlots()) { - if (inputSlot.windowsId == d->devMode->dmDefaultSource) { - value = inputSlot.id; - break; - } + if (d->devMode->dmDefaultSource >= DMBIN_USER) { + value = int(d->devMode->dmDefaultSource); + } else { + const QList inputSlots = d->m_printDevice.supportedInputSlots(); + const int index = indexOfWindowsId(inputSlots, d->devMode->dmDefaultSource); + value = index >= 0 ? inputSlots.at(index).id : QPrint::Auto; } } break; @@ -1371,7 +1387,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const case PPK_PaperSources: { QList out; foreach (const QPrint::InputSlot inputSlot, d->m_printDevice.supportedInputSlots()) - out << inputSlot.id; + out << QVariant(inputSlot.id == QPrint::CustomInputSlot ? inputSlot.windowsId : int(inputSlot.id)); value = out; break; } diff --git a/tests/manual/dialogs/printdialogpanel.cpp b/tests/manual/dialogs/printdialogpanel.cpp index 1a18f94406..e316486fcf 100644 --- a/tests/manual/dialogs/printdialogpanel.cpp +++ b/tests/manual/dialogs/printdialogpanel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. @@ -474,6 +474,15 @@ void PrintDialogPanel::retrieveSettings(const QPrinter *printer) setComboBoxValue(m_panel.m_colorModeCombo, printer->colorMode()); m_panel.m_resolution->setValue(printer->resolution()); +#ifdef Q_OS_WIN + QString availPaperSources; + foreach (QPrinter::PaperSource ps, printer->supportedPaperSources()) + availPaperSources += QString::number(int(ps)) + QLatin1Char(' '); + m_panel.availPaperSourceLabel->setText(availPaperSources); +#else + m_panel.availPaperSourceLabel->setText(QLatin1String("N/A")); +#endif + #if QT_VERSION >= 0x050300 m_pageLayout = printer->pageLayout(); #else diff --git a/tests/manual/dialogs/printdialogpanel.ui b/tests/manual/dialogs/printdialogpanel.ui index 2f0fe606a3..f4bab6fd9a 100644 --- a/tests/manual/dialogs/printdialogpanel.ui +++ b/tests/manual/dialogs/printdialogpanel.ui @@ -527,24 +527,24 @@ - + Color Mode: - + - + Resolution: - + @@ -584,6 +584,16 @@ + + + + Available Paper Sources: + + + + + + -- cgit v1.2.3 From 9b27240e4a30dd8b0d504f696f45c6c25caaa259 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sun, 18 May 2014 13:37:25 +0200 Subject: Fix the doc so it uses the defined parameter names for the signals The documentation needs to use the defined parameter names for the signals as this is what QML will make them available as if they are used in a connection to that signal. Task-number: QTBUG-35694 Change-Id: I0f56b9e1ace45cfff72c45273dd64766e3c792f2 Reviewed-by: Jerome Pasion --- src/corelib/itemmodels/qabstractitemmodel.cpp | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 4241fe08ca..ad5722626e 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -1504,10 +1504,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::rowsInserted(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::rowsInserted(const QModelIndex &parent, int first, int last) This signal is emitted after rows have been inserted into the - model. The new items are those between \a start and \a end + model. The new items are those between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes in the @@ -1532,10 +1532,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::rowsRemoved(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::rowsRemoved(const QModelIndex &parent, int first, int last) This signal is emitted after rows have been removed from the model. The - removed items are those between \a start and \a end inclusive, under the + removed items are those between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes @@ -1546,10 +1546,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last) This signal is emitted just before rows are removed from the model. The - items that will be removed are those between \a start and \a end inclusive, + items that will be removed are those between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes @@ -1624,10 +1624,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::columnsInserted(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::columnsInserted(const QModelIndex &parent, int first, int last) This signal is emitted after columns have been inserted into the model. The - new items are those between \a start and \a end inclusive, under the given + new items are those between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes in the @@ -1638,10 +1638,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::columnsAboutToBeInserted(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::columnsAboutToBeInserted(const QModelIndex &parent, int first, int last) This signal is emitted just before columns are inserted into the model. The - new items will be positioned between \a start and \a end inclusive, under + new items will be positioned between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes in the @@ -1652,10 +1652,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::columnsRemoved(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::columnsRemoved(const QModelIndex &parent, int first, int last) This signal is emitted after columns have been removed from the model. - The removed items are those between \a start and \a end inclusive, + The removed items are those between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes in @@ -1666,10 +1666,10 @@ QAbstractItemModel::~QAbstractItemModel() */ /*! - \fn void QAbstractItemModel::columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) + \fn void QAbstractItemModel::columnsAboutToBeRemoved(const QModelIndex &parent, int first, int last) This signal is emitted just before columns are removed from the model. The - items to be removed are those between \a start and \a end inclusive, under + items to be removed are those between \a first and \a last inclusive, under the given \a parent item. \note Components connected to this signal use it to adapt to changes in the -- cgit v1.2.3 From 1a4ff6f122f575aca21f6a0b9d9c14cac4a5ea66 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 25 May 2014 15:30:30 +0200 Subject: QOpenGLTexture: test for extensions when checking features Don't use only the GL version, as vendors expose many many extensions on viable hardware. For instance, I have a NVIDIA G210 which supports up to GL3.3, but which features immutable storage, immutable multisampled storage, texture buffers and ranges, stencil texturing, and cubemap arrays. Change-Id: Ie6023ee854b679737fca982578cb2093e10d083f Reviewed-by: Paul Lemire Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltexture.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 6b6d4bcf41..6e2e72a3b4 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2441,33 +2441,49 @@ bool QOpenGLTexture::hasFeature(Feature feature) if (!ctx->isOpenGLES()) { switch (feature) { case ImmutableMultisampleStorage: + supported = f.version() >= qMakePair(4, 3) + || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage_multisample")); + break; + case TextureBuffer: + supported = f.version() >= qMakePair(4, 3) + || (ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_object")) + && ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_buffer_range"))); + break; + case StencilTexturing: - supported = f.version() >= qMakePair(4, 3); + supported = f.version() >= qMakePair(4, 3) + || ctx->hasExtension(QByteArrayLiteral("GL_ARB_stencil_texturing")); break; case ImmutableStorage: - supported = f.version() >= qMakePair(4, 2); + supported = f.version() >= qMakePair(4, 2) + || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage")); break; case TextureCubeMapArrays: - supported = f.version() >= qMakePair(4, 0); + supported = f.version() >= qMakePair(4, 0) + || ctx->hasExtension(QByteArrayLiteral("ARB_texture_cube_map_array")); break; case Swizzle: - supported = f.version() >= qMakePair(3, 3); + supported = f.version() >= qMakePair(3, 3) + || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_swizzle")); break; case TextureMultisample: - supported = f.version() >= qMakePair(3, 2); + supported = f.version() >= qMakePair(3, 2) + || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_multisample")); break; case TextureArrays: - supported = f.version() >= qMakePair(3, 0); + supported = f.version() >= qMakePair(3, 0) + || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_array")); break; case TextureRectangle: - supported = f.version() >= qMakePair(2, 1); + supported = f.version() >= qMakePair(2, 1) + || ctx->hasExtension(QByteArrayLiteral("ARB_texture_rectangle")); break; case Texture3D: @@ -2798,7 +2814,7 @@ void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode) Q_ASSERT(d->texFuncs); Q_ASSERT(d->textureId); if (!d->features.testFlag(StencilTexturing)) { - qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3"); + qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3 or GL_ARB_stencil_texturing"); return; } d->depthStencilMode = mode; -- cgit v1.2.3 From 385692b3ad12f35d0008bc4b309225fcaac0010d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 25 May 2014 14:26:51 -0700 Subject: IPv6 scope ID of zero is not valid IANA reserves scope ID of 0x0 to mean "no scope ID", so make sure that we don't try to set it when reading from the sockaddr_in6 structure. Change-Id: I71b207e6f8262ab2bf9fde993288a71ba63c7572 Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine_unix.cpp | 12 +++++++----- src/network/socket/qnativesocketengine_win.cpp | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 6ee8b696df..65244ce9cf 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -111,13 +111,15 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po QHostAddress tmpAddress; tmpAddress.setAddress(tmp); *addr = tmpAddress; + if (s->a6.sin6_scope_id) { #ifndef QT_NO_IPV6IFNAME - char scopeid[IFNAMSIZ]; - if (::if_indextoname(s->a6.sin6_scope_id, scopeid)) { - addr->setScopeId(QLatin1String(scopeid)); - } else + char scopeid[IFNAMSIZ]; + if (::if_indextoname(s->a6.sin6_scope_id, scopeid)) { + addr->setScopeId(QLatin1String(scopeid)); + } else #endif - addr->setScopeId(QString::number(s->a6.sin6_scope_id)); + addr->setScopeId(QString::number(s->a6.sin6_scope_id)); + } } if (port) *port = ntohs(s->a6.sin6_port); diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index b1c9073eb9..138d046bfc 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -182,7 +182,8 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt if (address) { QHostAddress a; a.setAddress(tmp); - a.setScopeId(QString::number(sa6->sin6_scope_id)); + if (sa6->sin6_scope_id) + a.setScopeId(QString::number(sa6->sin6_scope_id)); *address = a; } if (port) -- cgit v1.2.3 From 92c6bfa0b238614db328bdc7a57cd0390adc95a5 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 14 May 2014 18:43:50 +0200 Subject: Fix loss of precision warnings Found by http://www.viva64.com/en/b/0251 Change-Id: I2a0c3dba74fef07c3119c9e57b343a8253ee7daa Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/plugins/platforms/windows/qwindowstabletsupport.cpp | 4 ++-- src/widgets/kernel/qstandardgestures.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 484ed9cb05..2a1e5c58b9 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -458,8 +458,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() // Z = sin(altitude) // X Tilt = arctan(X / Z) // Y Tilt = arctan(Y / Z) - const double radAzim = (packet.pkOrientation.orAzimuth / 10) * (M_PI / 180); - const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10)) * (M_PI / 180)); + const double radAzim = (packet.pkOrientation.orAzimuth / 10.0) * (M_PI / 180); + const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10.0)) * (M_PI / 180)); const double degX = atan(sin(radAzim) / tanAlt); const double degY = atan(cos(radAzim) / tanAlt); diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp index 64ab68257a..e57c3285d2 100644 --- a/src/widgets/kernel/qstandardgestures.cpp +++ b/src/widgets/kernel/qstandardgestures.cpp @@ -331,7 +331,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state, int elapsedTime = d->time.restart(); if (!elapsedTime) elapsedTime = 1; - d->velocityValue = 0.9 * d->velocityValue + distance / elapsedTime; + d->velocityValue = 0.9 * d->velocityValue + (qreal) distance / elapsedTime; d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle(); static const int MoveThreshold = 50; -- cgit v1.2.3 From f7af9fb63244b114653c157d3eef3e6c64f3196a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 23 May 2014 23:49:38 +0200 Subject: Account for the sort indicator being placed above the text on Vista In WindowsVista style and later the sort indicator is placed above the text as opposed to alongside it. Therefore the extra space given is moved to the common style allowing styles that have it placed differently to easily ensure it is not included. Task-number: QTBUG-19915 Change-Id: Ic21fcc1d95f4c3cc2eb9c465e1c8afb9b805389a Reviewed-by: Friedemann Kleint --- src/widgets/itemviews/qheaderview.cpp | 12 +++--------- src/widgets/styles/qcommonstyle.cpp | 7 +++++++ src/widgets/styles/qwindowsvistastyle.cpp | 13 +++++++++++++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index f1bdfc8709..eac25d3833 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2762,15 +2762,9 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const opt.icon = qvariant_cast(variant); if (opt.icon.isNull()) opt.icon = qvariant_cast(variant); - QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); - if (isSortIndicatorShown()) { - int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); - if (d->orientation == Qt::Horizontal) - size.rwidth() += size.height() + margin; - else - size.rheight() += size.width() + margin; - } - return size; + if (isSortIndicatorShown()) + opt.sortIndicator = QStyleOptionHeader::SortDown; + return style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); } /*! diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index f1cf46169a..d7030c5d72 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -4783,6 +4783,13 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz.setHeight(margin + qMax(iconSize, txt.height()) + margin); sz.setWidth((nullIcon ? 0 : margin) + iconSize + (hdr->text.isNull() ? 0 : margin) + txt.width() + margin); + if (hdr->sortIndicator != QStyleOptionHeader::None) { + int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, hdr, widget); + if (hdr->orientation == Qt::Horizontal) + sz.rwidth() += sz.height() + margin; + else + sz.rheight() += sz.width() + margin; + } } break; case CT_TabWidget: diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 9c3e1eac99..bc78ea3296 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -1970,6 +1970,19 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption sz -= QSize(2*border, 2*border); } return sz; + case CT_HeaderSection: + { + // When there is a sort indicator it adds to the width but it is shown + // above the text natively and not on the side + if (QStyleOptionHeader *hdr = qstyleoption_cast(const_cast(option))) { + QStyleOptionHeader::SortIndicator sortInd = hdr->sortIndicator; + hdr->sortIndicator = QStyleOptionHeader::None; + sz = QWindowsXPStyle::sizeFromContents(type, hdr, size, widget); + hdr->sortIndicator = sortInd; + return sz; + } + break; + } default: break; } -- cgit v1.2.3 From 5d48eb8bbc43b37235c29c2caf1e5fafec864b49 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 19 May 2014 19:58:35 +0200 Subject: Cocoa: Make sure modal windows get correct geometry on show MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit beginModalSessionForWindow will center the window and ignore the set geometry. So to workaround this it checks the new value against the old one and moves it back if need be. Change-Id: I38bc74c04138992f2e0570fca666414025aeeba8 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 6 +++++- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index e0ce9f9648..b625f233ce 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -622,7 +622,8 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() if (!info.session) { QCocoaAutoReleasePool pool; - NSWindow *nswindow = static_cast(info.window->handle())->nativeWindow(); + QCocoaWindow *cocoaWindow = static_cast(info.window->handle()); + NSWindow *nswindow = cocoaWindow->nativeWindow(); if (!nswindow) continue; @@ -630,7 +631,10 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() QBoolBlocker block1(blockSendPostedEvents, true); info.nswindow = nswindow; [(NSWindow*) info.nswindow retain]; + QRect rect = cocoaWindow->geometry(); info.session = [NSApp beginModalSessionForWindow:nswindow]; + if (rect != cocoaWindow->geometry()) + cocoaWindow->setGeometry(rect); } currentModalSessionCached = info.session; cleanupModalSessionsNeeded = false; diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 589f3e66e1..868288e36e 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -92,6 +92,7 @@ private slots: void modalDialogClosingOneOfTwoModal(); void modalWithChildWindow(); void modalWindowModallity(); + void modalWindowPosition(); void initTestCase() { @@ -1429,6 +1430,18 @@ void tst_QWindow::modalWindowModallity() } +void tst_QWindow::modalWindowPosition() +{ + QWindow window; + window.setGeometry(QRect(100, 100, 400, 400)); + // Allow for any potential resizing due to constraints + QRect origGeo = window.geometry(); + window.setModality(Qt::WindowModal); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QCOMPARE(window.geometry(), origGeo); +} + #include QTEST_MAIN(tst_QWindow) -- cgit v1.2.3 From 787c0d76a2d7dbc6d7493915f4f765ac19a14062 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 23 May 2014 12:14:02 +0200 Subject: Replace hard-coded qWait() by QTRY_COMPARE/VERIFY in widget tests. Task-number: QTBUG-38890 Change-Id: I9a729430fcd30b782c100bb76d5e287a3b4c1238 Reviewed-by: Robin Burchell --- tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp | 14 ++++---------- tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp | 8 +++----- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp index d02b86bd8a..7e0b0dac0c 100644 --- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp +++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp @@ -1726,9 +1726,8 @@ void tst_QMainWindow::addToolbarAfterShow() QToolBar toolBar; mainWindow.addToolBar(&toolBar); - QTest::qWait(100); - QVERIFY(!toolBar.isHidden()); + QTRY_VERIFY(!toolBar.isHidden()); } void tst_QMainWindow::centralWidgetSize() @@ -1743,8 +1742,7 @@ void tst_QMainWindow::centralWidgetSize() mainWindow.setCentralWidget(&widget); mainWindow.show(); - QTest::qWait(100); - QCOMPARE(widget.size(), widget.sizeHint()); + QTRY_COMPARE(widget.size(), widget.sizeHint()); } void tst_QMainWindow::dockWidgetSize() @@ -1789,19 +1787,15 @@ void tst_QMainWindow::QTBUG2774_stylechange() { - QTest::qWait(1000); mw.setStyleSheet("QMainWindow::separator { width: 50px; height:50px; }"); - QTest::qWait(5000); - QApplication::processEvents(); - QVERIFY(central->width() < centralOriginalWidth); + QTRY_VERIFY(central->width() < centralOriginalWidth); QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height()))); QVERIFY( mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 49))); } { mw.setStyleSheet("QMainWindow::separator { width: 0px; height: 0px; }"); - QApplication::processEvents(); - QVERIFY(central->width() > centralOriginalWidth); + QTRY_VERIFY(central->width() > centralOriginalWidth); QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height()))); QVERIFY(!mw.isSeparator(QPoint(4, dockw->pos().y() + dockw->size().height() + 1))); } diff --git a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp index a301d51c4c..8dd191e621 100644 --- a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp +++ b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp @@ -127,9 +127,7 @@ void tst_QStatusBar::tempMessage() QCOMPARE(testWidget->currentMessage(), QString("Ready")); QCOMPARE(testWidget->currentMessage(), currentMessage); - QTest::qWait(1000); - - QVERIFY(testWidget->currentMessage().isNull()); + QTRY_VERIFY(testWidget->currentMessage().isNull()); QVERIFY(currentMessage.isNull()); testWidget->showMessage("Ready again", 500); @@ -294,10 +292,10 @@ void tst_QStatusBar::QTBUG25492_msgtimeout() QCOMPARE(testWidget->currentMessage(), QString("Ready")); QCOMPARE(testWidget->currentMessage(), currentMessage); - QTest::qWait(3000); + QTest::qWait(1500); // Message disappears after 2 seconds - QVERIFY(testWidget->currentMessage().isNull()); + QTRY_VERIFY(testWidget->currentMessage().isNull()); QVERIFY(currentMessage.isNull()); // Set display message for 2 seconds first -- cgit v1.2.3 From 1b19f66037bd4942b7e699628f9bd8bde89a69bb Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 25 May 2014 21:39:22 +0100 Subject: Ensure all encrypted bytes are sent when closing QSslSocket. If you do sock->write(data) followed by sock->close() then the data written is not transmitted unless you flush when using QSslSocket but is when using QTcpSocket. This change makes QSslSocket work like QTcpSocket. Change-Id: Ia2e1c021dc48ac0d573f78da782ea77641c03bc1 Reviewed-by: Peter Hartmann --- src/network/ssl/qsslsocket.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index c5ae517fb0..de6e879a71 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -777,6 +777,8 @@ void QSslSocket::close() qDebug() << "QSslSocket::close()"; #endif Q_D(QSslSocket); + if (encryptedBytesToWrite()) + flush(); if (d->plainSocket) d->plainSocket->close(); QTcpSocket::close(); -- cgit v1.2.3 From 8701c20f0dcae0d6647675dbd2181610543b7926 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Fri, 23 May 2014 14:53:03 +0300 Subject: Direct2D QPA: Match raster engine line output For whatever reason direct2d and the raster engine disagree by one pixel about the positioning of positively sloping aliased lines. To get the same output, we shift such lines by one pixel. Change-Id: I4b20319770c02e3fdd212b3535ccae3c27ca9f2f Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index a1c405067c..4c39560cbe 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -1160,6 +1160,25 @@ void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount) } } +static bool isLinePositivelySloped(const QPointF &p1, const QPointF &p2) +{ + if (p2.x() > p1.x()) + return p2.y() < p1.y(); + + if (p1.x() > p2.x()) + return p1.y() < p2.y(); + + return false; +} + +static void adjustLine(QPointF *p1, QPointF *p2) +{ + if (isLinePositivelySloped(*p1, *p2)) { + p1->ry() -= qreal(1.0); + p2->ry() -= qreal(1.0); + } +} + void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QWindowsDirect2DPaintEngine); @@ -1181,6 +1200,10 @@ void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount) continue; } + // Match raster engine output + if (!antiAliasingEnabled()) + adjustLine(&p1, &p2); + adjustForAliasing(&p1); adjustForAliasing(&p2); @@ -1213,6 +1236,10 @@ void QWindowsDirect2DPaintEngine::drawLines(const QLineF *lines, int lineCount) continue; } + // Match raster engine output + if (!antiAliasingEnabled()) + adjustLine(&p1, &p2); + adjustForAliasing(&p1); adjustForAliasing(&p2); -- cgit v1.2.3 From 7ba0eb5a0daae59c495bbf250fa37a2627950e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 21 May 2014 11:30:54 +0200 Subject: Cocoa: Prevent crash on QWindow delete. Clear the QCocoaWindow pointer stored on the QNSWindowHelper when detaching from the platform window. This makes sure callbacks from cocoa does not try access deleted Qt window objects. Task-number: QTBUG-39141 Change-Id: I4672eae92940dcbd59a2848e56f94b50a828bbf6 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 651fedb26e..13e8dde012 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -182,6 +182,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)detachFromPlatformWindow { + _platformWindow = 0; [self.window.delegate release]; self.window.delegate = nil; } -- cgit v1.2.3 From 1ac0f953ba70ceda76e90918ab4ae7ebe2339969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 21 May 2014 11:36:54 +0200 Subject: Cocoa: Remove the NSWindow -> QCococaWindow hash. Cast the NSWindow to a QNSWindow instead. Now there is no way we can fail to maintain the hash properly. Change-Id: I5fd03b6fad964a61fadb3460b7063fd43ff25c79 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoaintegration.h | 3 --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 17 +++++------------ src/plugins/platforms/cocoa/qcocoawindow.mm | 5 ----- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 9c4f86d893..07b73c1a7a 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -139,8 +139,6 @@ public: void setToolbar(QWindow *window, NSToolbar *toolbar); NSToolbar *toolbar(QWindow *window) const; void clearToolbars(); - void setWindow(NSWindow* nsWindow, QCocoaWindow *window); - QCocoaWindow *window(NSWindow *window); private: static QCocoaIntegration *mInstance; @@ -159,7 +157,6 @@ private: QScopedPointer mKeyboardMapper; QHash mToolbars; - QHash mWindows; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index c4398622e8..19753ccc89 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -159,9 +159,12 @@ qreal QCocoaScreen::devicePixelRatio() const QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const { // Get a z-ordered list of windows. Iterate through it until - // we find a window which contains the point. + // we find a (Qt) window which contains the point. for (NSWindow *nsWindow in [NSApp orderedWindows]) { - QCocoaWindow *cocoaWindow = QCocoaIntegration::instance()->window(nsWindow); + if (![nsWindow isKindOfClass:[QNSWindow class]]) + continue; + QNSWindow *qnsWindow = static_cast(nsWindow); + QCocoaWindow *cocoaWindow = qnsWindow.helper.platformWindow; if (!cocoaWindow) continue; QWindow *window = cocoaWindow->window(); @@ -518,16 +521,6 @@ NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const return mToolbars.value(window); } -void QCocoaIntegration::setWindow(NSWindow* nsWindow, QCocoaWindow *window) -{ - mWindows.insert(nsWindow, window); -} - -QCocoaWindow *QCocoaIntegration::window(NSWindow *window) -{ - return mWindows.value(window); -} - void QCocoaIntegration::clearToolbars() { QHash::const_iterator it = mToolbars.constBegin(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 13e8dde012..0f51d0664c 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -262,8 +262,6 @@ static bool isMouseEvent(NSEvent *ev) { [self close]; - QCocoaIntegration::instance()->setWindow(self, 0); - if (self.helper.grabbingMouse) { self.helper.releaseOnMouseUp = YES; } else { @@ -330,7 +328,6 @@ static bool isMouseEvent(NSEvent *ev) { [self.helper detachFromPlatformWindow]; [self close]; - QCocoaIntegration::instance()->setWindow(self, 0); [self release]; } @@ -1414,8 +1411,6 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() applyContentBorderThickness(createdWindow); - QCocoaIntegration::instance()->setWindow(createdWindow, this); - return createdWindow; } -- cgit v1.2.3 From b214c177ea799baa33fe7ef7cf6446407928a38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 22 May 2014 09:38:34 +0200 Subject: Make QT_MAC_OPENGL_SURFACE_ORDER=-1 work better Mark the window as not opaque and give it a transparent background when layering OpenGL below the window. Change-Id: I2188842249c592f17619f7a2c3ef1fd30958987e Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 0f51d0664c..7ab7486ce9 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -999,9 +999,14 @@ bool QCocoaWindow::isExposed() const bool QCocoaWindow::isOpaque() const { + // OpenGL surfaces can be ordered either above(default) or below the NSWindow. + // When ordering below the window must be tranclucent. + static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER"); + bool translucent = (window()->format().alphaBufferSize() > 0 || window()->opacity() < 1 - || (m_qtView && [m_qtView hasMask])); + || (m_qtView && [m_qtView hasMask])) + || (surface()->supportsOpenGL() && openglSourfaceOrder == -1); return !translucent; } @@ -1402,7 +1407,13 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() NSInteger level = windowLevel(flags); [createdWindow setLevel:level]; - if (window()->format().alphaBufferSize() > 0) { + // OpenGL surfaces can be ordered either above(default) or below the NSWindow. + // When ordering below the window must be tranclucent and have a clear background color. + static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER"); + + bool isTranslucent = window()->format().alphaBufferSize() > 0 + || (surface()->supportsOpenGL() && openglSourfaceOrder == -1); + if (isTranslucent) { [createdWindow setBackgroundColor:[NSColor clearColor]]; [createdWindow setOpaque:NO]; } -- cgit v1.2.3 From 262d2cba12e9b164f9699951b37def21e1ed1652 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 26 May 2014 09:24:18 +0200 Subject: WinRT: Fix compile warnings Change-Id: If223dd73b9558a0f5144be38f19a61316f8c807b Reviewed-by: Oliver Wolff --- src/corelib/kernel/qsharedmemory_win.cpp | 2 ++ src/corelib/tools/qcollator_win.cpp | 1 + src/network/kernel/qhostaddress.cpp | 4 ++++ src/network/kernel/qhostinfo_winrt.cpp | 2 +- src/network/socket/qnativesocketengine_winrt.cpp | 4 ++-- src/plugins/platforms/winrt/qwinrtcursor.cpp | 2 ++ src/plugins/platforms/winrt/qwinrtplatformtheme.cpp | 2 ++ src/plugins/platforms/winrt/qwinrtscreen.cpp | 2 ++ src/widgets/kernel/qwidgetbackingstore.cpp | 3 +++ 9 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp index b00434977b..fd79a7efea 100644 --- a/src/corelib/kernel/qsharedmemory_win.cpp +++ b/src/corelib/kernel/qsharedmemory_win.cpp @@ -148,6 +148,7 @@ bool QSharedMemoryPrivate::create(int size) // Create the file mapping. #if defined(Q_OS_WINPHONE) Q_UNIMPLEMENTED(); + Q_UNUSED(size) hand = 0; #elif defined(Q_OS_WINRT) hand = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, size, (PCWSTR)nativeKey.utf16()); @@ -169,6 +170,7 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) int permissions = (mode == QSharedMemory::ReadOnly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS); #if defined(Q_OS_WINPHONE) Q_UNIMPLEMENTED(); + Q_UNUSED(mode) memory = 0; #elif defined(Q_OS_WINRT) memory = (void *)MapViewOfFileFromApp(handle(), permissions, 0, 0); diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp index 9a672a0505..4141ba1205 100644 --- a/src/corelib/tools/qcollator_win.cpp +++ b/src/corelib/tools/qcollator_win.cpp @@ -155,6 +155,7 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const #elif defined(Q_OS_WINPHONE) int size = 0; Q_UNIMPLEMENTED(); + Q_UNUSED(string) #else // Q_OS_WINPHONE int size = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator, reinterpret_cast(string.constData()), string.size(), diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 0ab72191dc..1d38d06ae9 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -453,6 +453,8 @@ QHostAddress::QHostAddress(const struct sockaddr *sockaddr) setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); +#else + Q_UNUSED(sockaddr) #endif } @@ -612,6 +614,8 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr) setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr)); else if (sockaddr->sa_family == AF_INET6) setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr); +#else + Q_UNUSED(sockaddr) #endif } diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp index 928c9e4628..92897f563d 100644 --- a/src/network/kernel/qhostinfo_winrt.cpp +++ b/src/network/kernel/qhostinfo_winrt.cpp @@ -84,7 +84,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) HStringReference classId(RuntimeClass_Windows_Networking_HostName); if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) - Q_ASSERT(false, "Could not obtain hostname factory."); + Q_ASSERT_X(false, "QHostInfoAgent", "Could not obtain hostname factory."); IHostName *host; HStringReference hostNameRef((const wchar_t*)hostName.utf16()); diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index db1d3dc96b..a32a757191 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -1159,7 +1159,7 @@ HRESULT QNativeSocketEnginePrivate::handleBindCompleted(IAsyncAction *, AsyncSta HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener *listener, IStreamSocketListenerConnectionReceivedEventArgs *args) { Q_Q(QNativeSocketEngine); - Q_ASSERT(tcpListener.Get() == listener); + Q_UNUSED(listener) IStreamSocket *socket; args->get_Socket(&socket); pendingConnections.append(socket); @@ -1253,7 +1253,7 @@ HRESULT QNativeSocketEnginePrivate::handleWriteCompleted(IAsyncOperationWithProg HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args) { Q_Q(QNativeSocketEngine); - Q_ASSERT(udp == socket); + Q_UNUSED(socket) pendingDatagrams.append(args); emit q->readReady(); diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp index 8241560cef..f09454ebc3 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.cpp +++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp @@ -135,6 +135,8 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *) ICoreCursor *cursor; if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor))) m_window->put_PointerCursor(cursor); +#else // Q_OS_WINPHONE + Q_UNUSED(windowCursor) #endif // Q_OS_WINPHONE } #endif // QT_NO_CURSOR diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp index e8f853e4b1..d4034ec571 100644 --- a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp +++ b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp @@ -53,6 +53,8 @@ bool QWinRTPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType typ #if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700) if (type == QPlatformTheme::MessageDialog) return true; +#else + Q_UNUSED(type) #endif // !(Q_OS_WINPHONE && _MSC_VER<=1700) return false; } diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 3fe856558f..f948cf9924 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -960,6 +960,8 @@ HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationPr { #ifndef Q_OS_WINPHONE args->put_AutomationProvider(m_inputContext); +#else + Q_UNUSED(args) #endif return S_OK; } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 221e6825ed..9d024fd359 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -168,6 +168,9 @@ static void showYellowThing_win(QWidget *widget, const QRegion ®ion, int msec void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped) { +#ifdef Q_OS_WINRT + Q_UNUSED(msec) +#endif QRegion paintRegion = toBePainted; QRect widgetRect = widget->rect(); -- cgit v1.2.3 From b732e56969940a9c3bbb1b4e09d671005e4a1006 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 23 May 2014 14:39:53 +0200 Subject: Android: Report current selection to the input method Task-number: QTBUG-39196 Change-Id: Ib798f1de83ccbe3830a746b6ddd435a0934c34cd Reviewed-by: J-P Nurmi Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../platforms/android/qandroidinputcontext.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index c2e5f83639..5d47d2fda4 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -472,12 +472,24 @@ void QAndroidInputContext::updateCursorPosition() if (m_composingText.isEmpty() != (m_composingTextStart == -1)) qWarning() << "Input method out of sync" << m_composingText << m_composingTextStart; - - // Qt's idea of the cursor position is the start of the preedit area, so we have to maintain our own preedit cursor pos int realCursorPosition = cursorPos; + int realAnchorPosition = cursorPos; + + int cpos = query->value(Qt::ImCursorPosition).toInt(); + int anchor = query->value(Qt::ImAnchorPosition).toInt(); + if (cpos != anchor) { + if (!m_composingText.isEmpty()) { + qWarning("Selecting text while preediting may give unpredictable results."); + finishComposingText(); + } + int blockPos = getBlockPosition(query); + realCursorPosition = blockPos + cpos; + realAnchorPosition = blockPos + anchor; + } + // Qt's idea of the cursor position is the start of the preedit area, so we maintain our own preedit cursor pos if (!m_composingText.isEmpty()) - realCursorPosition = m_composingCursor; - QtAndroidInput::updateSelection(realCursorPosition, realCursorPosition, //empty selection + realCursorPosition = realAnchorPosition = m_composingCursor; + QtAndroidInput::updateSelection(realCursorPosition, realAnchorPosition, m_composingTextStart, m_composingTextStart + composeLength); // pre-edit text } } -- cgit v1.2.3 From 13642424bb58fefff9d1439dbf6d17244a2ad6f5 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 26 May 2014 15:25:23 +0300 Subject: QOpenGLFramebufferObject: correct the internal format when using ANGLE As ANGLE doesn't support GL_RGBA as the internal format for its multisampled framebuffer extension, use GL_RGB8_OES to ensure a working out-of-the-box experience. Task-number: QTBUG-39283 Change-Id: Icb364225e74e5d3480a8617131a56e9f65f04ba5 Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- src/gui/opengl/qopenglframebufferobject.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 7fb6815120..7d91d2c497 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -453,10 +453,19 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi if (samples == 0) { initTexture(texture_target, internal_format, size, mipmap); } else { + GLenum storageFormat = internal_format; +#ifdef GL_RGBA8_OES + // Correct the internal format used by the render buffer when using ANGLE + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && internal_format == GL_RGBA + && strstr((const char *)funcs.glGetString(GL_RENDERER), "ANGLE") != 0) { + storageFormat = GL_RGBA8_OES; + } +#endif + mipmap = false; funcs.glGenRenderbuffers(1, &color_buffer); funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internal_format, size.width(), size.height()); + funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storageFormat, size.width(), size.height()); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer); QT_CHECK_GLERROR(); -- cgit v1.2.3 From 50491efb0e366f2a73b950d052adb9c621ea67eb Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 23 May 2014 20:21:31 +0200 Subject: Fix typos in comments (qfreelist and qmutex) Change-Id: I782b18b9f82a72a29371564838252e1838faf86c Reviewed-by: Olivier Goffart --- src/corelib/thread/qmutex_p.h | 2 +- src/corelib/tools/qfreelist_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h index bec2d934c1..dcaaed4cab 100644 --- a/src/corelib/thread/qmutex_p.h +++ b/src/corelib/thread/qmutex_p.h @@ -92,7 +92,7 @@ public: bool wait(int timeout = -1); void wakeUp() Q_DECL_NOTHROW; - // Conrol the lifetime of the privates + // Control the lifetime of the privates QAtomicInt refCount; int id; diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 5e90a03d7f..69b7fc67a0 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -81,7 +81,7 @@ struct QFreeListElement /*! \internal - Element in a QFreeList without a paylout. ConstReferenceType and + Element in a QFreeList without a payload. ConstReferenceType and ReferenceType are void, the t() functions return void and are empty. */ template <> -- cgit v1.2.3 From 8917179b47cf2ead645aaacfb680d261308cd866 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Sat, 24 May 2014 10:18:48 -0700 Subject: plugin/bearer remove static QDBusConnection::systemBus() initialization The static initialization of QDBusConnection::systemBus() can occur before the creation of QCoreApplication. This causes a warning from QDBusConnection and may cause the application to crash on exit. Since QDBusConnection::systemBus() is just an accessor, there is no real advantage to storing a static reference to it. Task-number: QTBUG-39248 Change-Id: I4401810c7c2ffd21a30f9ffd41b3a46e7e09214c Reviewed-by: Thiago Macieira Reviewed-by: Alex Blasche --- .../networkmanager/qnetworkmanagerservice.cpp | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index 776d69403a..c28f7ef664 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -58,8 +58,6 @@ QT_BEGIN_NAMESPACE -static QDBusConnection dbusConnection = QDBusConnection::systemBus(); - class QNetworkManagerInterfacePrivate { public: @@ -74,7 +72,7 @@ QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent) d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), QLatin1String(NM_DBUS_INTERFACE), - dbusConnection); + QDBusConnection::systemBus()); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -103,6 +101,9 @@ bool QNetworkManagerInterface::setConnections() { if(!isValid() ) return false; + + QDBusConnection dbusConnection = QDBusConnection::systemBus(); + bool allOk = false; if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), QLatin1String(NM_DBUS_PATH), @@ -198,7 +199,7 @@ QNetworkManagerInterfaceAccessPoint::QNetworkManagerInterfaceAccessPoint(const Q d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), - dbusConnection); + QDBusConnection::systemBus()); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -229,7 +230,7 @@ bool QNetworkManagerInterfaceAccessPoint::setConnections() connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - if(dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), QLatin1String("PropertiesChanged"), @@ -306,7 +307,7 @@ QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &de d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE), - dbusConnection); + QDBusConnection::systemBus()); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -335,7 +336,7 @@ bool QNetworkManagerInterfaceDevice::setConnections() nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper,SIGNAL(pathForStateChanged(QString,quint32)), this, SIGNAL(stateChanged(QString,quint32))); - if(dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE), QLatin1String("StateChanged"), @@ -397,7 +398,7 @@ QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const Q d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED), - dbusConnection, parent); + QDBusConnection::systemBus(), parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -428,7 +429,7 @@ bool QNetworkManagerInterfaceDeviceWired::setConnections() nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - if(dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED), QLatin1String("PropertiesChanged"), @@ -474,7 +475,7 @@ QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(c d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), - dbusConnection, parent); + QDBusConnection::systemBus(), parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -498,6 +499,7 @@ bool QNetworkManagerInterfaceDeviceWireless::setConnections() if(!isValid() ) return false; + QDBusConnection dbusConnection = QDBusConnection::systemBus(); bool allOk = false; delete nmDBusHelper; nmDBusHelper = new QNmDBusHelper(this); @@ -591,7 +593,7 @@ QNetworkManagerSettings::QNetworkManagerSettings(const QString &settingsService, d->connectionInterface = new QDBusInterface(settingsService, QLatin1String(NM_DBUS_PATH_SETTINGS), QLatin1String(NM_DBUS_IFACE_SETTINGS), - dbusConnection); + QDBusConnection::systemBus()); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -614,7 +616,7 @@ bool QNetworkManagerSettings::setConnections() { bool allOk = false; - if (!dbusConnection.connect(d->path, QLatin1String(NM_DBUS_PATH_SETTINGS), + if (!QDBusConnection::systemBus().connect(d->path, QLatin1String(NM_DBUS_PATH_SETTINGS), QLatin1String(NM_DBUS_IFACE_SETTINGS), QLatin1String("NewConnection"), this, SIGNAL(newConnection(QDBusObjectPath)))) { allOk = true; @@ -655,7 +657,7 @@ QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QStri d->connectionInterface = new QDBusInterface(settingsService, d->path, QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), - dbusConnection, parent); + QDBusConnection::systemBus(), parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -681,6 +683,7 @@ bool QNetworkManagerSettingsConnection::setConnections() if(!isValid() ) return false; + QDBusConnection dbusConnection = QDBusConnection::systemBus(); bool allOk = false; if(!dbusConnection.connect(d->service, d->path, QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), QLatin1String("Updated"), @@ -808,7 +811,7 @@ QNetworkManagerConnectionActive::QNetworkManagerConnectionActive( const QString d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION), - dbusConnection, parent); + QDBusConnection::systemBus(), parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; @@ -837,7 +840,7 @@ bool QNetworkManagerConnectionActive::setConnections() nmDBusHelper = new QNmDBusHelper(this); connect(nmDBusHelper, SIGNAL(pathForPropertiesChanged(QString,QMap)), this,SIGNAL(propertiesChanged(QString,QMap))); - if(dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), + if (QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION), QLatin1String("PropertiesChanged"), @@ -902,7 +905,7 @@ QNetworkManagerIp4Config::QNetworkManagerIp4Config( const QString &deviceObjectP d->connectionInterface = new QDBusInterface(QLatin1String(NM_DBUS_SERVICE), d->path, QLatin1String(NM_DBUS_INTERFACE_IP4_CONFIG), - dbusConnection, parent); + QDBusConnection::systemBus(), parent); if (!d->connectionInterface->isValid()) { d->valid = false; return; -- cgit v1.2.3 From d0c38291eb8c58b85c5df21afe6c3b729b3cb492 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 21 Feb 2014 16:26:32 -0800 Subject: UTF-8: always store the SIMD result, even if invalid For ASCII content, this improves the throughput because the conditional is no longer on the codepath to storing, so the processor can perform the store at the same time as it's doing the movemask operation. However, the gain is mostly theoretical: benchmarking with mostly ASCII content shows the algorithm running within 0.5% of the previous result (which is noise). For non-ASCII content, we're comparing the cost of doing a 16-byte store (which may be completely overwritten) with the loop copying and shifting left. Benchmarking shows a slight gain of a few percent. Change-Id: I28ef0021dffc725a922c539cc5976db367f36e78 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/codecs/qutfcodec.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index c5f580e13d..4fb32dcc59 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -74,25 +74,22 @@ static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const __m128i packed = _mm_packus_epi16(data1, data2); __m128i nonAscii = _mm_cmpgt_epi8(packed, _mm_setzero_si128()); + // store, even if there are non-ASCII characters here + _mm_storeu_si128((__m128i*)dst, packed); + // n will contain 1 bit set per character in [data1, data2] that is non-ASCII (or NUL) ushort n = ~_mm_movemask_epi8(nonAscii); if (n) { - // copy the front part that is still ASCII - while (!(n & 1)) { - *dst++ = *src++; - n >>= 1; - } - // find the next probable ASCII character // we don't want to load 32 bytes again in this loop if we know there are non-ASCII // characters still coming - n = _bit_scan_reverse(n); - nextAscii = src + n + 1; + nextAscii = src + _bit_scan_reverse(n) + 1; + + n = _bit_scan_forward(n); + dst += n; + src += n; return false; } - - // pack - _mm_storeu_si128((__m128i*)dst, packed); } return src == end; } -- cgit v1.2.3 From d153e4628e7643cf02b795f68f739c4bced15389 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 26 May 2014 13:20:40 +0200 Subject: Initialize the count variable used in SQLNumResultCols to 0 If the call to SQLNumResultCols fails for whatever reason then it will not be correctly caught since the count might be higher than 0 since it is uninitalized. This ensures that if it fails then it does not try to act as if it succeeded. Task-number: QTBUG-39137 Change-Id: Ifae8c1f7fac8416643f2317747f87295642a7935 Reviewed-by: Mark Brand --- src/sql/drivers/db2/qsql_db2.cpp | 6 +++--- src/sql/drivers/odbc/qsql_odbc.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index d799060633..9fbe1ac6f8 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -555,7 +555,7 @@ bool QDB2Result::reset (const QString& query) "Unable to execute statement"), QSqlError::StatementError, d)); return false; } - SQLSMALLINT count; + SQLSMALLINT count = 0; r = SQLNumResultCols(d->hStmt, &count); if (count) { setSelect(true); @@ -795,7 +795,7 @@ bool QDB2Result::exec() "Unable to execute statement"), QSqlError::StatementError, d)); return false; } - SQLSMALLINT count; + SQLSMALLINT count = 0; r = SQLNumResultCols(d->hStmt, &count); if (count) { setSelect(true); @@ -1105,7 +1105,7 @@ bool QDB2Result::nextResult() return false; } - SQLSMALLINT fieldCount; + SQLSMALLINT fieldCount = 0; r = SQLNumResultCols(d->hStmt, &fieldCount); setSelect(fieldCount > 0); for (int i = 0; i < fieldCount; ++i) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index c950d2c2ef..23eff8dbe3 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -963,7 +963,7 @@ bool QODBCResult::reset (const QString& query) if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE); - SQLSMALLINT count; + SQLSMALLINT count = 0; SQLNumResultCols(d->hStmt, &count); if (count) { setSelect(true); @@ -1591,7 +1591,7 @@ bool QODBCResult::exec() if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE); - SQLSMALLINT count; + SQLSMALLINT count = 0; SQLNumResultCols(d->hStmt, &count); if (count) { setSelect(true); @@ -1723,7 +1723,7 @@ bool QODBCResult::nextResult() } } - SQLSMALLINT count; + SQLSMALLINT count = 0; SQLNumResultCols(d->hStmt, &count); if (count) { setSelect(true); -- cgit v1.2.3 From 8746a6a3e2a21f952badd6301565783f07f61c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 20 May 2014 13:01:50 +0200 Subject: Improve the implementation of the _NET_WM_SYNC_REQUEST protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change improves the synced resizes of xcb windows and adds support for synced resizes of glx windows. The QXcbWindow keeps a better track on whether the window manager expects a sync and can be in one of three states: * no sync required * sync required, but configure notify event not yet received * sync required and configured By tracking this in the QXcbWindow itself the backing store can make use of this information and doesn't need an own heuristic to decide whether a sync is needed. Also this allows to add support for synced resizes of windows with an OpenGLSurface. This is accomplished by checking the sync state after swapping buffers. As the OpenGL context may be bound to a background thread the sync is done using a QueuedConnection to ensure that the sync happens in the thread which created the xcb window. So far this is only added for GLX. This significantly improves the resize experience of QQuickWindow and also the initial mapping with a composited window manager in case the compositor uses the sync protocol to determine whether the window is ready to get painted on screen. Change-Id: Ied0261873043d785dec652d2821fc3638292fa36 Reviewed-by: Uli Schlachter Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qglxintegration.cpp | 9 +++++++++ src/plugins/platforms/xcb/qxcbbackingstore.cpp | 16 ++++------------ src/plugins/platforms/xcb/qxcbbackingstore.h | 1 - src/plugins/platforms/xcb/qxcbconnection.cpp | 5 +++++ src/plugins/platforms/xcb/qxcbconnection.h | 3 +++ src/plugins/platforms/xcb/qxcbintegration.cpp | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 25 +++++++++++++++++++++++-- src/plugins/platforms/xcb/qxcbwindow.h | 15 ++++++++++++++- 8 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index f78d3bcc4e..9a56455940 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -390,6 +390,15 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface) else glxDrawable = static_cast(surface)->xcb_window(); glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable); + + if (surface->surface()->surfaceClass() == QSurface::Window) { + QXcbWindow *platformWindow = static_cast(surface); + // OpenGL context might be bound to a non-gui thread + // use QueuedConnection to sync the window from the platformWindow's thread + // as QXcbWindow is no QObject, a wrapper slot in QXcbConnection is used. + if (platformWindow->needsSync()) + QMetaObject::invokeMethod(m_screen->connection(), "syncWindow", Qt::QueuedConnection, Q_ARG(QXcbWindow*, platformWindow)); + } } void (*QGLXContext::getProcAddress(const QByteArray &procName)) () diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 57d6bc580b..ada5b0eedf 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -261,7 +261,6 @@ void QXcbShmImage::preparePaint(const QRegion ®ion) QXcbBackingStore::QXcbBackingStore(QWindow *window) : QPlatformBackingStore(window) , m_image(0) - , m_syncingResize(false) { QXcbScreen *screen = static_cast(window->screen()->handle()); setConnection(screen->connection()); @@ -330,13 +329,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin Q_XCB_NOOP(connection()); - if (m_syncingResize) { - connection()->sync(); - m_syncingResize = false; + if (platformWindow->needsSync()) platformWindow->updateSyncRequestCounter(); - } else { + else xcb_flush(xcb_connection()); - } } #ifndef QT_NO_OPENGL @@ -347,10 +343,8 @@ void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, c Q_XCB_NOOP(connection()); - if (m_syncingResize) { - QXcbWindow *platformWindow = static_cast(window->handle()); - connection()->sync(); - m_syncingResize = false; + QXcbWindow *platformWindow = static_cast(window->handle()); + if (platformWindow->needsSync()) { platformWindow->updateSyncRequestCounter(); } else { xcb_flush(xcb_connection()); @@ -376,8 +370,6 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) delete m_image; m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); Q_XCB_NOOP(connection()); - - m_syncingResize = true; } extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h index 19a5ac62d0..af3c004c2d 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.h +++ b/src/plugins/platforms/xcb/qxcbbackingstore.h @@ -72,7 +72,6 @@ public: private: QXcbShmImage *m_image; - bool m_syncingResize; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index f5f6c712c5..1b72bb0da1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1833,6 +1833,11 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() return m_systemTrayTracker; } +void QXcbConnection::syncWindow(QXcbWindow *window) +{ + window->updateSyncRequestCounter(); +} + QXcbConnectionGrabber::QXcbConnectionGrabber(QXcbConnection *connection) :m_connection(connection) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 6e511356c4..f96541318c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -464,6 +464,9 @@ public: void handleEnterEvent(const xcb_enter_notify_event_t *); #endif +public slots: + void syncWindow(QXcbWindow *window); + private slots: void processXcbEvents(); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 0bab341914..ddb164bf07 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -127,6 +127,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char : m_services(new QGenericUnixServices) , m_instanceName(0) { + qRegisterMetaType(); #ifdef XCB_USE_XLIB XInitThreads(); #endif diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3645b6469a..a46fe437d8 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -200,6 +200,7 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_eglSurface(0) #endif , m_lastWindowStateEvent(-1) + , m_syncState(NoSyncNeeded) { m_screen = static_cast(window->screen()->handle()); @@ -367,7 +368,12 @@ void QXcbWindow::create() properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS); properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING); - m_usingSyncProtocol = m_screen->syncRequestSupported() && window()->surfaceType() != QSurface::OpenGLSurface; + m_usingSyncProtocol = m_screen->syncRequestSupported(); +#if !defined(XCB_USE_GLX) + // synced resize only implemented on GLX + if (window()->supportsOpenGL()) + m_usingSyncProtocol = false; +#endif if (m_usingSyncProtocol) properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST); @@ -1596,6 +1602,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even connection()->setTime(event->data.data32[1]); m_syncValue.lo = event->data.data32[2]; m_syncValue.hi = event->data.data32[3]; + if (m_usingSyncProtocol) + m_syncState = SyncReceived; #ifndef QT_NO_WHATSTHIS } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) { QWindowSystemInterface::handleEnterWhatsThisEvent(); @@ -1669,6 +1677,9 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t * QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); } + if (m_usingSyncProtocol && m_syncState == SyncReceived) + m_syncState = SyncAndConfigureReceived; + m_dirtyFrameMargins = true; } @@ -1945,12 +1956,17 @@ void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) void QXcbWindow::updateSyncRequestCounter() { + if (m_syncState != SyncAndConfigureReceived) { + // window manager does not expect a sync event yet. + return; + } if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) { Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue)); - connection()->sync(); + xcb_flush(xcb_connection()); m_syncValue.lo = 0; m_syncValue.hi = 0; + m_syncState = NoSyncNeeded; } } @@ -2173,4 +2189,9 @@ void QXcbWindow::setAlertState(bool enabled) } } +bool QXcbWindow::needsSync() const +{ + return m_syncState == SyncAndConfigureReceived; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 12d17023fb..b924ee27e5 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -144,13 +144,17 @@ public: void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); - void updateSyncRequestCounter(); void updateNetWmUserTime(xcb_timestamp_t timestamp); #if defined(XCB_USE_EGL) QXcbEGLSurface *eglSurface() const; #endif + bool needsSync() const; + +public Q_SLOTS: + void updateSyncRequestCounter(); + private: void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); NetWmStates netWmStates(); @@ -217,8 +221,17 @@ private: xcb_visualid_t m_visualId; int m_lastWindowStateEvent; + + enum SyncState { + NoSyncNeeded, + SyncReceived, + SyncAndConfigureReceived + }; + SyncState m_syncState; }; QT_END_NAMESPACE +Q_DECLARE_METATYPE(QXcbWindow*) + #endif -- cgit v1.2.3 From 34590e84d4aaceb5874d8acb6a2b7a95c153cd6a Mon Sep 17 00:00:00 2001 From: Arnaud Bienner Date: Tue, 13 May 2014 20:19:12 +0200 Subject: Doc: be more explicit about need to set expected SSL cert in errors Note added in QNetworkReply and QSslSocket documentation. Task-number: QTBUG-16770 Change-Id: I2dd8cfb913ec29a96b5465a905cd213713b8d537 Reviewed-by: Richard J. Moore --- src/network/access/qnetworkreply.cpp | 3 ++- src/network/ssl/qsslsocket.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index bfe870c783..2d9a128559 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -657,7 +657,8 @@ void QNetworkReply::setSslConfiguration(const QSslConfiguration &config) If this function is called, the SSL errors given in \a errors will be ignored. - Note that you can set the expected certificate in the SSL error: + \note Because most SSL errors are associated with a certificate, for most + of them you must set the expected certificate this SSL error is related to. If, for instance, you want to issue a request to a server that uses a self-signed certificate, consider the following snippet: diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index de6e879a71..90f6e25b97 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1771,7 +1771,8 @@ void QSslSocket::ignoreSslErrors() This method tells QSslSocket to ignore only the errors given in \a errors. - Note that you can set the expected certificate in the SSL error: + \note Because most SSL errors are associated with a certificate, for most + of them you must set the expected certificate this SSL error is related to. If, for instance, you want to connect to a server that uses a self-signed certificate, consider the following snippet: -- cgit v1.2.3 From 5fbc1f39ae82e8d2f452a8040723d6cfcb88f0c6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 27 May 2014 12:25:08 +0200 Subject: Fix fast painting of clipped text on non RGB32 formats QRasterPaintEngine::alphaPenBlt makes the assumption that a device with bit depth 32 has optimized alphamapBlit and alphaRGBBlit routines. This will fail on RGBA8888 format resulting in some text not being rendered. Change-Id: Ia7d88bb0e3094894affceda1acc42396b67b3677 Reviewed-by: Gunnar Sletta --- src/gui/painting/qpaintengine_raster.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index ce8c1d1ca7..a004428fab 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2603,7 +2603,7 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx return; } } - } else if (d->deviceDepth == 32 && (depth == 8 || depth == 32)) { + } else if (d->deviceDepth == 32 && ((depth == 8 && s->penData.alphamapBlit) || (depth == 32 && s->penData.alphaRGBBlit))) { // (A)RGB Alpha mask where the alpha component is not used. if (!clip) { int nx = qMax(0, rx); @@ -2626,13 +2626,12 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx rx = nx; ry = ny; } - if (depth == 8 && s->penData.alphamapBlit) { + if (depth == 8) s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color, scanline, w, h, bpl, clip); - } else if (depth == 32 && s->penData.alphaRGBBlit) { + else if (depth == 32) s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color, (const uint *) scanline, w, h, bpl / 4, clip); - } return; } } -- cgit v1.2.3 From 6e32a58428fc0cf95dd3c7cae6286be5ce44a833 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 May 2014 11:26:38 -0700 Subject: Remove unused QMapNode{,Base}::minimumNode These functions are not used anywhere. Since the classes are not documented, we're free to remove the inline functions. The implementation of the const function in QMapNode is also bogus: it discards a const qualifier. Task-number: QTBUG-39301 Change-Id: Ib8fd10a4da4b58a62cef17017ea6127c4d964325 Reviewed-by: Lars Knoll --- src/corelib/tools/qmap.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 76f8bd6f17..d7bd9c739c 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -102,9 +102,6 @@ struct Q_CORE_EXPORT QMapNodeBase void setColor(Color c) { if (c == Black) p |= Black; else p &= ~Black; } QMapNodeBase *parent() const { return reinterpret_cast(p & ~Mask); } void setParent(QMapNodeBase *pp) { p = (p & Mask) | quintptr(pp); } - - QMapNodeBase *minimumNode() { QMapNodeBase *n = this; while (n->left) n = n->left; return n; } - const QMapNodeBase *minimumNode() const { const QMapNodeBase *n = this; while (n->left) n = n->left; return n; } }; template @@ -121,9 +118,6 @@ struct QMapNode : public QMapNodeBase inline QMapNode *nextNode() { return static_cast(QMapNodeBase::nextNode()); } inline QMapNode *previousNode() { return static_cast(QMapNodeBase::previousNode()); } - QMapNode *minimumNode() { return static_cast(QMapNodeBase::minimumNode()); } - const QMapNode *minimumNode() const { return static_cast(QMapNodeBase::minimumNode()); } - QMapNode *copy(QMapData *d) const; void destroySubTree(); -- cgit v1.2.3 From 1d58face30c2936657c4372c6237e2fe64e4095b Mon Sep 17 00:00:00 2001 From: Liang Jian Date: Wed, 28 May 2014 12:56:00 +0800 Subject: Fix QOpenGLGlyphTexture object leak Call clear() in the destructor of QOpenGLTextureGlyphCache class to prevent QOpenGLGlyphTexture object leak. Change-Id: I290b09b0786d30603391e6855a21e9232b112739 Reviewed-by: Gunnar Sletta --- src/gui/opengl/qopengltextureglyphcache.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index f721d5cb8c..0610ab60ed 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -87,6 +87,7 @@ QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache() #ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG qDebug(" -> ~QOpenGLTextureGlyphCache() %p.", this); #endif + clear(); } static inline bool isCoreProfile() @@ -447,7 +448,8 @@ int QOpenGLTextureGlyphCache::maxTextureHeight() const void QOpenGLTextureGlyphCache::clear() { - m_textureResource->free(); + if (m_textureResource) + m_textureResource->free(); m_textureResource = 0; m_w = 0; -- cgit v1.2.3 From 626e0f204e846040e8e3a67bfc088f09b5091e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 14 May 2014 11:30:35 +0200 Subject: Revert "Cocoa: Post event to "show()" a modal window" This reverts commit a9cbddf4739f3cfabd38367b5f872fe2c1a3814c. The reverted commit is an incorrect bug-fix for a regression introduced by adding a call to [NSApp abortModal] in change d9875f7b. Change-Id: If23463ebdfe2ff64c68739dbece73a13773683c9 Reviewed-by: Gabriel de Dietrich --- .../platforms/cocoa/qcocoaeventdispatcher.h | 3 +-- .../platforms/cocoa/qcocoaeventdispatcher.mm | 25 ++++++++++------------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index de6c6585e9..0274ed8201 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -134,8 +134,6 @@ public: void interrupt(); void flush(); - bool event(QEvent *); - friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; @@ -165,6 +163,7 @@ public: // The following variables help organizing modal sessions: QStack cocoaModalSessionStack; bool currentExecIsNSAppRun; + bool modalSessionOnNSAppRun; bool nsAppRunCalledByQt; bool cleanupModalSessionsNeeded; uint processEventsCalled; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index b625f233ce..98becf0728 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -738,25 +738,13 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) updateChildrenWorksWhenModal(); currentModalSessionCached = 0; if (currentExecIsNSAppRun) { - QEvent *e = new QEvent(QEvent::User); - qApp->postEvent(q, e, Qt::HighEventPriority); + modalSessionOnNSAppRun = true; + q->wakeUp(); } else { q->interrupt(); } } -bool QCocoaEventDispatcher::event(QEvent *e) -{ - Q_D(QCocoaEventDispatcher); - - if (e->type() == QEvent::User) { - d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents); - return true; - } - - return QObject::event(e); -} - void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) { Q_Q(QCocoaEventDispatcher); @@ -793,6 +781,7 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() runLoopTimerRef(0), blockSendPostedEvents(false), currentExecIsNSAppRun(false), + modalSessionOnNSAppRun(false), nsAppRunCalledByQt(false), cleanupModalSessionsNeeded(false), processEventsCalled(0), @@ -923,6 +912,14 @@ void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info) // processEvents() was called "manually," ignore this source for now d->maybeCancelWaitForMoreEvents(); return; + } else if (d->modalSessionOnNSAppRun) { + // We're about to spawn the 1st modal session on top of the main runloop. + // Instead of calling processPostedEvents(), which would need us stop + // NSApp, we just re-enter processEvents(). This is equivalent to calling + // QDialog::exec() except that it's done in a non-blocking way. + d->modalSessionOnNSAppRun = false; + d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents); + return; } d->processPostedEvents(); d->maybeCancelWaitForMoreEvents(); -- cgit v1.2.3 From 385ba9e7e3604fa181e89ae7242a6b1a36544c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 14 May 2014 11:30:46 +0200 Subject: Revert "Cocoa: Don't stop NSApp when showing a modal dialog" This reverts commit ff3dcc49c4a1912189091e35e87cb61af2f62d47. The reverted commit is an incorrect bug-fix for a regression introduced by adding a call to [NSApp abortModal] in change d9875f7b. Change-Id: I1307d1790ada740e0552d62267b6009cbccd6c4c Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 1 - src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 16 +--------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 0274ed8201..33d7dcbcf4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -163,7 +163,6 @@ public: // The following variables help organizing modal sessions: QStack cocoaModalSessionStack; bool currentExecIsNSAppRun; - bool modalSessionOnNSAppRun; bool nsAppRunCalledByQt; bool cleanupModalSessionsNeeded; uint processEventsCalled; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 98becf0728..97b8771354 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -725,6 +725,7 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) // setting currentModalSessionCached to zero, so that interrupt() calls // [NSApp abortModal] if another modal session is currently running Q_Q(QCocoaEventDispatcher); + q->interrupt(); // Add a new, empty (null), NSModalSession to the stack. // It will become active the next time QEventDispatcher::processEvents is called. @@ -737,12 +738,6 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) cocoaModalSessionStack.push(info); updateChildrenWorksWhenModal(); currentModalSessionCached = 0; - if (currentExecIsNSAppRun) { - modalSessionOnNSAppRun = true; - q->wakeUp(); - } else { - q->interrupt(); - } } void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) @@ -781,7 +776,6 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() runLoopTimerRef(0), blockSendPostedEvents(false), currentExecIsNSAppRun(false), - modalSessionOnNSAppRun(false), nsAppRunCalledByQt(false), cleanupModalSessionsNeeded(false), processEventsCalled(0), @@ -912,14 +906,6 @@ void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info) // processEvents() was called "manually," ignore this source for now d->maybeCancelWaitForMoreEvents(); return; - } else if (d->modalSessionOnNSAppRun) { - // We're about to spawn the 1st modal session on top of the main runloop. - // Instead of calling processPostedEvents(), which would need us stop - // NSApp, we just re-enter processEvents(). This is equivalent to calling - // QDialog::exec() except that it's done in a non-blocking way. - d->modalSessionOnNSAppRun = false; - d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents); - return; } d->processPostedEvents(); d->maybeCancelWaitForMoreEvents(); -- cgit v1.2.3 From 11fdc4f6c06922b474a311d7afb8a393686ddf13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 14 May 2014 11:32:54 +0200 Subject: Partially revert "Cocoa: support modal windows" This reverts parts of commit d9875f7bff6d52a52a1d0bf4002044a5304cf6bf, in particular the code for "2. Make interrupt() use [NSApp abortModal]" abortModal is not the right way to end a modal session, and introduced bad side effects, as reported in QTBUG-34677. Restore this part of the event dispatcher to the Qt 4 state. Change-Id: Iacc2d4a0757807c87c4320c93ed4db186622945c Reviewed-by: Gabriel de Dietrich --- .../platforms/cocoa/qcocoaeventdispatcher.mm | 36 ++++++++-------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 97b8771354..96a8fa1ad4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -721,9 +721,7 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) { // We need to start spinning the modal session. Usually this is done with // QDialog::exec() for Qt Widgets based applications, but for others that - // just call show(), we need to interrupt(). We call this here, before - // setting currentModalSessionCached to zero, so that interrupt() calls - // [NSApp abortModal] if another modal session is currently running + // just call show(), we need to interrupt(). Q_Q(QCocoaEventDispatcher); q->interrupt(); @@ -759,10 +757,7 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) info.window = 0; if (i + endedSessions == stackSize-1) { // The top sessions ended. Interrupt the event dispatcher to - // start spinning the correct session immediately. Like in - // beginModalSession(), we call interrupt() before clearing - // currentModalSessionCached to make sure we stop any currently - // running modal session with [NSApp abortModal] + // start spinning the correct session immediately. q->interrupt(); currentModalSessionCached = 0; cleanupModalSessionsNeeded = true; @@ -935,23 +930,16 @@ void QCocoaEventDispatcher::interrupt() { Q_D(QCocoaEventDispatcher); d->interrupt = true; - if (d->currentModalSessionCached) { - // If a modal session is active, abort it so that we can clean it up - // later. We can't use [NSApp stopModal] here, because we do not know - // where the interrupt() came from. - [NSApp abortModal]; - } else { - wakeUp(); - - // We do nothing more here than setting d->interrupt = true, and - // poke the event loop if it is sleeping. Actually stopping - // NSApp, or the current modal session, is done inside the send - // posted events callback. We do this to ensure that all current pending - // cocoa events gets delivered before we stop. Otherwise, if we now stop - // the last event loop recursion, cocoa will just drop pending posted - // events on the floor before we get a chance to reestablish a new session. - d->cancelWaitForMoreEvents(); - } + wakeUp(); + + // We do nothing more here than setting d->interrupt = true, and + // poke the event loop if it is sleeping. Actually stopping + // NSApp, or the current modal session, is done inside the send + // posted events callback. We do this to ensure that all current pending + // cocoa events gets delivered before we stop. Otherwise, if we now stop + // the last event loop recursion, cocoa will just drop pending posted + // events on the floor before we get a chance to reestablish a new session. + d->cancelWaitForMoreEvents(); } void QCocoaEventDispatcher::flush() -- cgit v1.2.3 From 530607d8ba0dac8d91d20ec0e62d3129cb21e225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 15 May 2014 13:29:25 +0200 Subject: Cocoa: Fix modal session cleanup. Call [NSApp endModalSession] at the correct time. Calling cleanupModalSessions() from processPostedEvents() resulted in endModalSession being called from within [NSApp runModalSession] - ending and cleaning up the the modal session while Cocoa is still using it. Move the cleanupModalSessions() call to to after runModalSession returns. Task-number: QTBUG-37699 Change-Id: I5868def36f6869667b0bbe33733286e3e49488eb Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 96a8fa1ad4..9aaf08adcf 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -415,6 +415,11 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) // 'session' as well. As a result, we need to restart all internal sessions: d->temporarilyStopAllModalSessions(); } + + // Clean up the modal session list, call endModalSession. + if (d->cleanupModalSessionsNeeded) + d->cleanupModalSessions(); + } else { d->nsAppRunCalledByQt = true; QBoolBlocker execGuard(d->currentExecIsNSAppRun, true); @@ -441,6 +446,11 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) // 'session' as well. As a result, we need to restart all internal sessions: d->temporarilyStopAllModalSessions(); } + + // Clean up the modal session list, call endModalSession. + if (d->cleanupModalSessionsNeeded) + d->cleanupModalSessions(); + retVal = true; } else do { // Dispatch all non-user events (but que non-user events up for later). In @@ -860,9 +870,6 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() return; } - if (cleanupModalSessionsNeeded) - cleanupModalSessions(); - if (interrupt) { if (currentExecIsNSAppRun) { // The event dispatcher has been interrupted. But since -- cgit v1.2.3 From 3e38944118a0195620a6c4bff591155cdd560b63 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Fri, 23 May 2014 17:35:10 +0200 Subject: doc: Updated Qt D-Bus Examples. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -transferred group page from qtdoc repository -added description in example pages -set the example documentation to use the standard Qt thumbnail -added an entry in the help index for the example page Change-Id: I9d5747bc329b5ecc15acd2eb3139696931166c6f Reviewed-by: Topi Reiniö --- examples/dbus/doc/images/dbus-chat-example.png | Bin 0 -> 38530 bytes examples/dbus/doc/src/chat.qdoc | 12 ++++++- examples/dbus/doc/src/complexpingpong.qdoc | 14 +++++++- examples/dbus/doc/src/listnames.qdoc | 10 +++++- examples/dbus/doc/src/pingpong.qdoc | 19 ++++++++++- .../doc/src/dbus-remotecontrolledcar.qdoc | 10 ++++-- src/dbus/doc/qtdbus.qdocconf | 12 +++++-- src/dbus/doc/src/qtdbus-examples.qdoc | 38 +++++++++++++++++++++ src/dbus/doc/src/qtdbus-index.qdoc | 1 + 9 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 examples/dbus/doc/images/dbus-chat-example.png create mode 100644 src/dbus/doc/src/qtdbus-examples.qdoc diff --git a/examples/dbus/doc/images/dbus-chat-example.png b/examples/dbus/doc/images/dbus-chat-example.png new file mode 100644 index 0000000000..ad66d08950 Binary files /dev/null and b/examples/dbus/doc/images/dbus-chat-example.png differ diff --git a/examples/dbus/doc/src/chat.qdoc b/examples/dbus/doc/src/chat.qdoc index 45b1260140..daf3eccc9a 100644 --- a/examples/dbus/doc/src/chat.qdoc +++ b/examples/dbus/doc/src/chat.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -28,4 +28,14 @@ /*! \example chat \title D-Bus Chat Example + \ingroup examples-dbus + \brief Demonstrates communication among instances of an application. + + \e Chat is a \l{Qt D-Bus} example which demonstrates a simple chat system + among instances of an application. Users connect and send message to + each other. + + \image dbus-chat-example.png + + \include examples-run.qdocinc */ diff --git a/examples/dbus/doc/src/complexpingpong.qdoc b/examples/dbus/doc/src/complexpingpong.qdoc index b4cac193fc..ef9df18eab 100644 --- a/examples/dbus/doc/src/complexpingpong.qdoc +++ b/examples/dbus/doc/src/complexpingpong.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -28,4 +28,16 @@ /*! \example complexpingpong \title D-Bus Complex Ping Pong Example + \ingroup examples-dbus + \brief Demonstrates usage of the Qt D-Bus typesystem. + + \e{Complex Ping Pong Example} demonstrates the use of \l{Qt D-Bus} + typesystem with QDBusVariant and QDBusReply. The example consists of the + main application \c complexping which starts the other application, \c + complexpong. Entering keywords such as \c hello and \c ping is handled by + complexpong and the reply is printed to the standard output. + + \include examples-run.qdocinc + + To run, execute the \c complexping application. */ diff --git a/examples/dbus/doc/src/listnames.qdoc b/examples/dbus/doc/src/listnames.qdoc index 5e17db9674..a0376e10a7 100644 --- a/examples/dbus/doc/src/listnames.qdoc +++ b/examples/dbus/doc/src/listnames.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -28,4 +28,12 @@ /*! \example listnames \title D-Bus List Names Example + \ingroup examples-dbus + \brief Shows how to access the D-Bus bus daemon service. + + \e{List Names} is a command-line example which shows how to + access the \l{Qt D-Bus} bus daemon service. The example prints various + information about the bus daemon service. + + \include examples-run.qdocinc */ diff --git a/examples/dbus/doc/src/pingpong.qdoc b/examples/dbus/doc/src/pingpong.qdoc index c7dc110077..dcaeb12043 100644 --- a/examples/dbus/doc/src/pingpong.qdoc +++ b/examples/dbus/doc/src/pingpong.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -28,4 +28,21 @@ /*! \example pingpong \title D-Bus Ping Pong Example + \ingroup examples-dbus + \brief Demonstrates a simple message system using D-Bus. + + \e{Ping Pong} is a command-line example that demonstrates the basics of + \l{Qt D-Bus}. A message is sent to another application and there is a + confirmation of the message. + + \include examples-run.qdocinc + + Run the \c pong application and run the \c ping application with the message + as the argument. + + \badcode + $ ./pong & + $ ./ping Hello + Reply was: ping("Hello") got called + \endcode */ diff --git a/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc b/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc index 522b0bacc7..a485a99299 100644 --- a/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc +++ b/examples/dbus/remotecontrolledcar/doc/src/dbus-remotecontrolledcar.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -28,9 +28,13 @@ /*! \example remotecontrolledcar \title D-Bus Remote Controlled Car Example + \ingroup examples-dbus + \brief Shows how to use Qt D-Bus to control a car from another application. - The Remote Controlled Car example shows how to use D-Bus to control one - application using another. + The Remote Controlled Car example shows how to use \l{Qt D-Bus} to control + one application from another. \image remotecontrolledcar-car-example.png + + \include examples-run.qdocinc */ diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf index 1233ae3d47..ff46cc5961 100644 --- a/src/dbus/doc/qtdbus.qdocconf +++ b/src/dbus/doc/qtdbus.qdocconf @@ -13,7 +13,8 @@ exampledirs += ../../../examples/dbus \ snippets headerdirs += .. -imagedirs += images +imagedirs += images \ + ../../../examples/dbus/doc/images sourcedirs += .. \ ../../../examples/dbus/doc/src excludedirs += ../../../examples/widgets/doc @@ -44,11 +45,18 @@ qhp.QtDBus.indexTitle = Qt D-Bus # Only update the name of the project for the next variables. qhp.QtDBus.virtualFolder = qtdbus -qhp.QtDBus.subprojects = classes +qhp.QtDBus.subprojects = classes examples qhp.QtDBus.subprojects.classes.title = C++ Classes qhp.QtDBus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes qhp.QtDBus.subprojects.classes.selectors = class fake:headerfile qhp.QtDBus.subprojects.classes.sortPages = true +qhp.QtDBus.subprojects.examples.title = Examples +qhp.QtDBus.subprojects.examples.indexTitle = Qt D-Bus Examples +qhp.QtDBus.subprojects.examples.selectors = fake:example navigation.landingpage = "Qt D-Bus" navigation.cppclassespage = "Qt D-Bus C++ Classes" + +manifestmeta.thumbnail.names = "QtDBus/D-Bus List Names Example" \ + "QtDBus/D-Bus Ping Pong Example" \ + "QtDBus/D-Bus Complex Ping Pong Example" \ diff --git a/src/dbus/doc/src/qtdbus-examples.qdoc b/src/dbus/doc/src/qtdbus-examples.qdoc new file mode 100644 index 0000000000..c0dde656b6 --- /dev/null +++ b/src/dbus/doc/src/qtdbus-examples.qdoc @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group examples-dbus + \title Qt D-Bus Examples + \brief Using D-Bus from Qt applications. + \ingroup all-examples + + \l{Qt D-Bus} allows applications to send messages to each other using + D-Bus. This page lists examples which specifically use D-Bus for + inter-process communication (IPC). + +*/ diff --git a/src/dbus/doc/src/qtdbus-index.qdoc b/src/dbus/doc/src/qtdbus-index.qdoc index b7c2ddbc92..2249924ada 100644 --- a/src/dbus/doc/src/qtdbus-index.qdoc +++ b/src/dbus/doc/src/qtdbus-index.qdoc @@ -211,5 +211,6 @@ \li \l{The Qt D-Bus Type System} \li \l{Qt D-Bus XML compiler (qdbusxml2cpp)} \li \l{Qt D-Bus C++ Classes} + \li \l{Qt D-Bus Examples} \endlist */ -- cgit v1.2.3 From 9857da723dc9e7795b84de106d8bfb6ef9456090 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 23 May 2014 11:02:08 +0200 Subject: Remove the need for the dot in OS X/iOS bundle prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes the need for the user to put a dot at the end of the bundle prefix which makes it's use more consistent and intuitive. The prefix is based on what Xcode calls the "Company Identifier", basically "com.digia" plus the product name. Changing that to "com.digia.prefix-" and the product name to "Foo" results in a bundle identifier of "com.digia.prefix-.Foo" which is in line with Xcode. Change-Id: I9b62fc4dee1df51b523ce890a8896ea58ea2c62d Reviewed-by: Oswald Buddenhagen Reviewed-by: Tor Arne Vestbø --- qmake/generators/unix/unixmake2.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d1e363626d..cc375f5c46 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -748,8 +748,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString icon = fileFixify(var("ICON")); QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString(); if (bundlePrefix.isEmpty()) - bundlePrefix = "com.yourcompany."; - QString bundleIdentifier = bundlePrefix + var("QMAKE_BUNDLE"); + bundlePrefix = "com.yourcompany"; + if (bundlePrefix.endsWith(".")) + bundlePrefix.chop(1); + QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE"); if (bundleIdentifier.endsWith(".app")) bundleIdentifier.chop(4); t << "@$(DEL_FILE) " << info_plist_out << "\n\t" -- cgit v1.2.3 From 52ff4120a29e915215ea06499ae08e17ba997074 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 14 May 2014 14:17:37 +0200 Subject: Fix Null pointer dereferencing in an error handler identified by static analysis from http://www.viva64.com/en/b/0251/ Change-Id: I0042336d9598415b978bf9819e74639685c627b5 Reviewed-by: Martin Smith --- src/tools/qdoc/qdocindexfiles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp index 47e302dad6..00c9c55020 100644 --- a/src/tools/qdoc/qdocindexfiles.cpp +++ b/src/tools/qdoc/qdocindexfiles.cpp @@ -536,7 +536,7 @@ void QDocIndexFiles::readIndexSection(const QDomElement& element, } else { qDebug() << "NODE:" << node->name() << "GROUPS:" << groupNames; - qDebug() << "DID NOT FIND GROUP:" << dn->name() << "for:" << node->name(); + qDebug() << "DID NOT FIND GROUP for:" << node->name(); } } } -- cgit v1.2.3 From 3478ec29494c315c4e41f25a1265da928503694b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 May 2014 14:53:08 +0200 Subject: Move native subwidgets in QWidget::scroll(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-38999 Change-Id: Ie22dcf61895bbfc575eaae4d1929516a8749de39 Reviewed-by: Jørgen Lind --- src/widgets/kernel/qwidget_p.h | 2 +- src/widgets/kernel/qwidget_qpa.cpp | 10 ++++----- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 26 ++++++++++++++++++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 99cba0e20f..9586d1a8c9 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -609,7 +609,7 @@ public: } } - void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect()); + void setWSGeometry(); inline QPoint mapToWS(const QPoint &p) const { return p - data.wrect.topLeft(); } diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 5ba0a90d3d..17ed4ca477 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -1027,11 +1027,11 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) q->windowHandle()->setOpacity(level); } -void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) +void QWidgetPrivate::setWSGeometry() { - Q_UNUSED(dontShow); - Q_UNUSED(oldRect); - // XXX + Q_Q(QWidget); + if (QWindow *window = q->windowHandle()) + window->setGeometry(data.crect); } QPaintEngine *QWidget::paintEngine() const diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 2a70431223..34936fa5b8 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -288,6 +288,7 @@ private slots: #ifndef Q_OS_MAC void scroll(); + void scrollNativeChildren(); #endif // tests QWidget::setGeometry() @@ -4336,7 +4337,30 @@ void tst_QWidget::scroll() QTRY_COMPARE(updateWidget.paintedRegion, dirty); } } -#endif + +// QTBUG-38999, scrolling a widget with native child widgets should move the children. +void tst_QWidget::scrollNativeChildren() +{ + QWidget parent; + parent.setWindowTitle(QLatin1String(__FUNCTION__)); + parent.resize(400, 400); + centerOnScreen(&parent); + QLabel *nativeLabel = new QLabel(QStringLiteral("nativeLabel"), &parent); + const QPoint oldLabelPos(100, 100); + nativeLabel->move(oldLabelPos); + QVERIFY(nativeLabel->winId()); + parent.show(); + QVERIFY(QTest::qWaitForWindowExposed(&parent)); + const QPoint delta(50, 50); + parent.scroll(delta.x(), delta.y()); + const QPoint newLabelPos = oldLabelPos + delta; + QWindow *labelWindow = nativeLabel->windowHandle(); + QVERIFY(labelWindow); + QTRY_COMPARE(labelWindow->geometry().topLeft(), newLabelPos); + QTRY_COMPARE(nativeLabel->geometry().topLeft(), newLabelPos); +} + +#endif // Mac OS class DestroyedSlotChecker : public QObject { -- cgit v1.2.3 From 909b0de5d16f2af3b3d6a3ca4c7e53b84836ad37 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 15 May 2014 13:32:27 +0200 Subject: Windows: Fix another crash when creating QRawFont from invalid data The sanity check added in d16508a285a5423ae9a5034e969801bce74ffb98 didn't actually catch the case where the invalid data is large enough to contain the offset table and table directory. Added sanity checks to all the code that accesses the font data now, so this should fix crashes with partial data as well as invalid data. Task-number: QTBUG-37190 Change-Id: Ie43f10d8cf0b09007783b9b1c4d91bfed8c6b0f0 Reviewed-by: Konstantin Ritt --- .../platforms/windows/qwindowsfontdatabase.cpp | 36 ++++++++++++++++------ tests/auto/gui/text/qrawfont/tst_qrawfont.cpp | 5 +++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 6d9f01da4e..696dc06cee 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -164,15 +164,18 @@ namespace { { Q_ASSERT(tagName.size() == 4); quint32 tagId = *(reinterpret_cast(tagName.constData())); - - if (m_fontData.size() < sizeof(OffsetSubTable) + sizeof(TableDirectory)) + if (Q_UNLIKELY(m_fontData.size() < sizeof(OffsetSubTable))) return 0; OffsetSubTable *offsetSubTable = reinterpret_cast(m_fontData.data()); TableDirectory *tableDirectory = reinterpret_cast(offsetSubTable + 1); + quint16 tableCount = qFromBigEndian(offsetSubTable->numTables); + if (Q_UNLIKELY(quint32(m_fontData.size()) < sizeof(OffsetSubTable) + sizeof(TableDirectory) * tableCount)) + return 0; + TableDirectory *nameTableDirectoryEntry = 0; - for (int i = 0; i < qFromBigEndian(offsetSubTable->numTables); ++i, ++tableDirectory) { + for (int i = 0; i < tableCount; ++i, ++tableDirectory) { if (tableDirectory->identifier == tagId) { nameTableDirectoryEntry = tableDirectory; break; @@ -190,19 +193,34 @@ namespace { nameTableDirectoryEntry = tableDirectoryEntry("name"); if (nameTableDirectoryEntry != 0) { - NameTable *nameTable = reinterpret_cast( - m_fontData.data() + qFromBigEndian(nameTableDirectoryEntry->offset)); + quint32 offset = qFromBigEndian(nameTableDirectoryEntry->offset); + if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameTable))) + return QString(); + + NameTable *nameTable = reinterpret_cast(m_fontData.data() + offset); NameRecord *nameRecord = reinterpret_cast(nameTable + 1); - for (int i = 0; i < qFromBigEndian(nameTable->count); ++i, ++nameRecord) { + + quint16 nameTableCount = qFromBigEndian(nameTable->count); + if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameRecord) * nameTableCount)) + return QString(); + + for (int i = 0; i < nameTableCount; ++i, ++nameRecord) { if (qFromBigEndian(nameRecord->nameID) == 1 && qFromBigEndian(nameRecord->platformID) == 3 // Windows && qFromBigEndian(nameRecord->languageID) == 0x0409) { // US English + quint16 stringOffset = qFromBigEndian(nameTable->stringOffset); + quint16 nameOffset = qFromBigEndian(nameRecord->offset); + quint16 nameLength = qFromBigEndian(nameRecord->length); + + if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + stringOffset + nameOffset + nameLength)) + return QString(); + const void *ptr = reinterpret_cast(nameTable) - + qFromBigEndian(nameTable->stringOffset) - + qFromBigEndian(nameRecord->offset); + + stringOffset + + nameOffset; const quint16 *s = reinterpret_cast(ptr); - const quint16 *e = s + qFromBigEndian(nameRecord->length) / sizeof(quint16); + const quint16 *e = s + nameLength / sizeof(quint16); while (s != e) name += QChar( qFromBigEndian(*s++)); break; diff --git a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp index 20bfaf99dd..a39277b093 100644 --- a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp @@ -948,6 +948,11 @@ void tst_QRawFont::rawFontFromInvalidData() font.loadFromData(invalidData, 10, QFont::PreferDefaultHinting); QVERIFY(!font.isValid()); + + invalidData.fill(255, 1024); + font.loadFromData(invalidData, 10, QFont::PreferDefaultHinting); + + QVERIFY(!font.isValid()); } #endif // QT_NO_RAWFONT -- cgit v1.2.3 From 267ba8b63e0fbf02cde4d2709397ed0e12f34ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= Date: Mon, 24 Mar 2014 19:17:43 +0100 Subject: QAbstractProxyModel::sibling: treat row/column as offsets within the proxy Qt5 allows QAIM subclasses to reimplement the sibling() method. Unfortunately, the default QAbstractProxyModel's reimplementation differs in behavior to what the Qt4 version was doing. In particular, the Qt4 version used to use the row and column as positions within the proxy model, while the Qt5 version mistakenly does this at the level of source model. This is arguably broken; the caller asks for a sibling of the proxy index, not for a sibling within the proxy model. This change makes the QAPM::sibling work explicitly in the same way as the Qt4 code behaved. The reimplementation of QAbstractProxyModel::sibling was introduced in 9dfba89c28bbff3316cb7aed6c07f90c0f2d5a22. It was subsequently fixed with commit 999109866dbd350a29cc70815d0c772545c85746 not to return indexes from the source model, but the logic was still different from the Qt4 version. [ChangeLog][QtCore][QAbstractProxyModel] Fixed QAbstractProxyModel::sibling to work in the same manner as the Qt4 code used to behave. Previously, Qt5's implementation would treat the row and column as positions in the source model instead of a position in the proxy itself. Followup-to 9dfba89c28bbff3316cb7aed6c07f90c0f2d5a22 and 999109866dbd350a29cc70815d0c772545c85746 Change-Id: Ia25027b2ad9e4777ba28de2d2226d48f8cccf587 Reviewed-by: Olivier Goffart Reviewed-by: Mark Brand Reviewed-by: Stephen Kelly --- src/corelib/itemmodels/qabstractproxymodel.cpp | 3 +- .../tst_qabstractproxymodel.cpp | 98 ++++++++++++++++++++++ 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index d435c4bcf5..2f1f4921f7 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -377,8 +377,7 @@ bool QAbstractProxyModel::hasChildren(const QModelIndex &parent) const */ QModelIndex QAbstractProxyModel::sibling(int row, int column, const QModelIndex &idx) const { - Q_D(const QAbstractProxyModel); - return mapFromSource(d->model->sibling(row, column, mapToSource(idx))); + return index(row, column, idx.parent()); } /*! diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp index c385a02b9c..f36bbbc5b6 100644 --- a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp @@ -71,6 +71,7 @@ private slots: void submit_data(); void submit(); void testRoleNames(); + void testSwappingRowsProxy(); }; // Subclass that exposes the protected functions. @@ -397,6 +398,103 @@ void tst_QAbstractProxyModel::testRoleNames() QVERIFY( proxy2RoleNames.value(StandardItemModelWithCustomRoleNames::CustomRole2) == "custom2" ); } +// This class only supports very simple table models +class SwappingProxy : public QAbstractProxyModel +{ + static int swapRow(const int row) + { + if (row == 2) { + return 3; + } else if (row == 3) { + return 2; + } else { + return row; + } + } +public: + virtual QModelIndex index(int row, int column, const QModelIndex &parentIdx) const + { + if (!sourceModel()) + return QModelIndex(); + if (row < 0 || column < 0) + return QModelIndex(); + if (row >= sourceModel()->rowCount()) + return QModelIndex(); + if (column >= sourceModel()->columnCount()) + return QModelIndex(); + return createIndex(row, column, parentIdx.internalPointer()); + } + + virtual QModelIndex parent(const QModelIndex &parentIdx) const + { + // well, we're a 2D model + Q_UNUSED(parentIdx); + return QModelIndex(); + } + + virtual int rowCount(const QModelIndex &parentIdx) const + { + if (parentIdx.isValid() || !sourceModel()) + return 0; + return sourceModel()->rowCount(); + } + + virtual int columnCount(const QModelIndex &parentIdx) const + { + if (parentIdx.isValid() || !sourceModel()) + return 0; + return sourceModel()->rowCount(); + } + + virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const + { + if (!proxyIndex.isValid()) + return QModelIndex(); + if (!sourceModel()) + return QModelIndex(); + Q_ASSERT(!proxyIndex.parent().isValid()); + return sourceModel()->index(swapRow(proxyIndex.row()), proxyIndex.column(), QModelIndex()); + } + + virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const + { + if (!sourceIndex.isValid()) + return QModelIndex(); + if (!sourceModel()) + return QModelIndex(); + Q_ASSERT(!sourceIndex.parent().isValid()); + return index(swapRow(sourceIndex.row()), sourceIndex.column(), QModelIndex()); + } +}; + +void tst_QAbstractProxyModel::testSwappingRowsProxy() +{ + QStandardItemModel defaultModel; + defaultModel.setRowCount(4); + defaultModel.setColumnCount(2); + for (int row = 0; row < defaultModel.rowCount(); ++row) { + defaultModel.setItem(row, 0, new QStandardItem(QString::number(row) + QLatin1Char('A'))); + defaultModel.setItem(row, 1, new QStandardItem(QString::number(row) + QLatin1Char('B'))); + } + SwappingProxy proxy; + proxy.setSourceModel(&defaultModel); + QCOMPARE(proxy.data(proxy.index(0, 0, QModelIndex())), QVariant("0A")); + QCOMPARE(proxy.data(proxy.index(0, 1, QModelIndex())), QVariant("0B")); + QCOMPARE(proxy.data(proxy.index(1, 0, QModelIndex())), QVariant("1A")); + QCOMPARE(proxy.data(proxy.index(1, 1, QModelIndex())), QVariant("1B")); + QCOMPARE(proxy.data(proxy.index(2, 0, QModelIndex())), QVariant("3A")); + QCOMPARE(proxy.data(proxy.index(2, 1, QModelIndex())), QVariant("3B")); + QCOMPARE(proxy.data(proxy.index(3, 0, QModelIndex())), QVariant("2A")); + QCOMPARE(proxy.data(proxy.index(3, 1, QModelIndex())), QVariant("2B")); + + for (int row = 0; row < defaultModel.rowCount(); ++row) { + QModelIndex left = proxy.index(row, 0, QModelIndex()); + QModelIndex right = proxy.index(row, 1, QModelIndex()); + QCOMPARE(left.sibling(left.row(), 1), right); + QCOMPARE(right.sibling(right.row(), 0), left); + } +} + QTEST_MAIN(tst_QAbstractProxyModel) #include "tst_qabstractproxymodel.moc" -- cgit v1.2.3 From 7547158bc8347e374e746296412b952f6bd55f62 Mon Sep 17 00:00:00 2001 From: Daiwei Li Date: Sun, 25 May 2014 18:18:48 -0700 Subject: CMake: Fix build with unversion_libname configuration a162a3cb (Android: Add "unversioned_libname" configuration, 2014-04-23) removed the version for shared libs on Android. This change updates the generated CMake files to support that. Change-Id: Ia6ef04872c664bd4c31546456a82730babed2910 Reviewed-by: Oswald Buddenhagen Reviewed-by: Stephen Kelly --- mkspecs/features/create_cmake.prf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index ac5fe22d75..aee3e79765 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -239,6 +239,10 @@ mac { CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.a CMAKE_PRL_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.prl CMAKE_PRL_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.prl + } else:unversioned_libname { + CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.so + CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.so + CMAKE_LIB_SONAME = lib$${CMAKE_QT_STEM}.so } else { CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}.so.$$eval(QT.$${MODULE}.VERSION) CMAKE_LIB_FILE_LOCATION_RELEASE = lib$${CMAKE_QT_STEM}.so.$$eval(QT.$${MODULE}.VERSION) -- cgit v1.2.3 From bfc0b27b4b2cba117a5f1e00e2ec8ac13d2af586 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Fri, 30 May 2014 10:37:41 +0200 Subject: Do not resolve the java functions for each call Instead do it only once (in registerNatives). This is seems to be the preferred way of doing it in other parts of the platform plugin. Change-Id: I361a7862bb5a24b4024c7c6a30ecb14fc515d4ff Reviewed-by: Frederik Gladhorn --- .../platforms/android/androidjniaccessibility.cpp | 62 ++++++++++++++-------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index fa7e259460..d9f5cec27a 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -56,6 +56,18 @@ static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; namespace QtAndroidAccessibility { + static jmethodID m_addActionMethodID = 0; + static jmethodID m_setCheckableMethodID = 0; + static jmethodID m_setCheckedMethodID = 0; + static jmethodID m_setClickableMethodID = 0; + static jmethodID m_setContentDescriptionMethodID = 0; + static jmethodID m_setEnabledMethodID = 0; + static jmethodID m_setFocusableMethodID = 0; + static jmethodID m_setFocusedMethodID = 0; + static jmethodID m_setTextSelectionMethodID = 0; + static jmethodID m_setVisibleToUserMethodID = 0; + + static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active) { QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration(); @@ -164,17 +176,6 @@ if (!clazz) { \ //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); -#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \ -{ \ - jclass clazz = env->GetObjectClass(OBJECT); \ - jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \ - if (!method) { \ - __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ - return false; \ - } \ - env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \ -} - static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId) { @@ -210,30 +211,30 @@ if (!clazz) { \ int startSelection; int endSelection; textIface->selection(0, &startSelection, &endSelection); - CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection) + env->CallVoidMethod(node, m_setTextSelectionMethodID, startSelection, endSelection); } } - CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled) - CALL_METHOD(node, "setFocusable", "(Z)V", (bool)state.focusable) - CALL_METHOD(node, "setFocused", "(Z)V", (bool)state.focused) - CALL_METHOD(node, "setCheckable", "(Z)V", (bool)state.checkable) - CALL_METHOD(node, "setChecked", "(Z)V", (bool)state.checked) - CALL_METHOD(node, "setVisibleToUser", "(Z)V", !state.invisible) + env->CallVoidMethod(node, m_setEnabledMethodID, !state.disabled); + env->CallVoidMethod(node, m_setCheckedMethodID, (bool)state.checked); + env->CallVoidMethod(node, m_setFocusableMethodID, (bool)state.focusable); + env->CallVoidMethod(node, m_setFocusedMethodID, (bool)state.focused); + env->CallVoidMethod(node, m_setCheckableMethodID, (bool)state.checkable); + env->CallVoidMethod(node, m_setVisibleToUserMethodID, !state.invisible); if (iface->actionInterface()) { QStringList actions = iface->actionInterface()->actionNames(); bool clickable = actions.contains(QAccessibleActionInterface::pressAction()); bool toggle = actions.contains(QAccessibleActionInterface::toggleAction()); if (clickable || toggle) { - CALL_METHOD(node, "setClickable", "(Z)V", (bool)clickable) - CALL_METHOD(node, "addAction", "(I)V", 16) // ACTION_CLICK defined in AccessibilityNodeInfo + env->CallVoidMethod(node, m_setClickableMethodID, (bool)clickable); + env->CallVoidMethod(node, m_addActionMethodID, (int)16); // ACTION_CLICK defined in AccessibilityNodeInfo } } jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size()); //CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc) - CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc) + env->CallVoidMethod(node, m_setContentDescriptionMethodID, jdesc); return true; } @@ -249,6 +250,13 @@ if (!clazz) { \ {"clickAction", "(I)Z", (void*)clickAction}, }; +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ + VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ + if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \ + return false; \ + } + bool registerNatives(JNIEnv *env) { jclass clazz; @@ -260,6 +268,18 @@ if (!clazz) { \ return false; } + jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo"); + GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V"); + GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V"); + GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V"); + GET_AND_CHECK_STATIC_METHOD(m_setClickableMethodID, nodeInfoClass, "setClickable", "(Z)V"); + GET_AND_CHECK_STATIC_METHOD(m_setContentDescriptionMethodID, nodeInfoClass, "setContentDescription", "(Ljava/lang/CharSequence;)V"); + GET_AND_CHECK_STATIC_METHOD(m_setEnabledMethodID, nodeInfoClass, "setEnabled", "(Z)V"); + GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V"); + GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V"); + GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V"); + GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V"); + return true; } } -- cgit v1.2.3 From 2d75c21923d3a74a6eafa11945e14a2cb7533059 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 May 2014 09:36:15 -0700 Subject: Update the QSignalBlocker docs to show actual behavior QSignalBlocker resets to the previous state, which might have already been a blocked signal state. Task-number: QTBUG-39352 Change-Id: I918cc6ea346755b940e027cee5d6704824fbba32 Reviewed-by: David Faure --- src/corelib/kernel/qobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 0e9cbfe1c9..38e55b7aa9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -513,7 +513,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object) \code const bool wasBlocked = someQObject->blockSignals(true); // no signals here - someQObject->blockSignals(false); + someQObject->blockSignals(wasBlocked); \endcode except the code using QSignalBlocker is safe in the face of -- cgit v1.2.3 From 42f9a61608fe662e797dc6541f4e82c19b878d56 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 30 May 2014 17:56:03 -0400 Subject: Fix QSysInfo::macVersion for OS X minor versions greater than 9. gestaltSystemVersion's encoding only has room for a single version digit. Thus, OS X 10.10 would previously have been detected as OS X 10.9 (Apple's comments in the header even warn against this). Change-Id: I41c35b1507d39e2958a9aaffaa8c48ac380f61d9 Reviewed-by: Samuel Gaist Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 66664f0f2a..d7c166721e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1770,8 +1770,9 @@ QSysInfo::MacVersion QSysInfo::macVersion() { #if defined(Q_OS_OSX) SInt32 gestalt_version; - if (Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) { - return QSysInfo::MacVersion(((gestalt_version & 0x00F0) >> 4) + 2); + if (Gestalt(gestaltSystemVersionMinor, &gestalt_version) == noErr) { + // add 2 because OS X 10.0 is 0x02 in the enum + return QSysInfo::MacVersion(gestalt_version + 2); } #elif defined(Q_OS_IOS) return qt_ios_version(); // qtcore_mac_objc.mm -- cgit v1.2.3 From 4a7083dd2750ddfa11bf93becc177384514f2963 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Fri, 23 May 2014 15:04:06 +0200 Subject: QDialogButtonBox does not need TabFocus It will now share the same behavior as QGroupBox, which has NoFocus if its not checkable. This doesn't lure AT clients to stop and read its content (this is the case for android accessibility) (designer seems to generate a tooltip for each QDialogButtonBox, which will be read as the name). Change-Id: I6cfacdd9c01299521222c773634df1e36971d982 Reviewed-by: Frederik Gladhorn --- src/widgets/widgets/qdialogbuttonbox.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 3acd4f0701..86fc6fff5d 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -211,9 +211,6 @@ void QDialogButtonBoxPrivate::initLayout() q->setSizePolicy(sp); q->setAttribute(Qt::WA_WState_OwnSizePolicy, false); } - - // ### move to a real init() function - q->setFocusPolicy(Qt::TabFocus); } void QDialogButtonBoxPrivate::resetLayout() -- cgit v1.2.3 From 64de8fb29dd43fd0f204e5b06236051512a9eef4 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 2 Jun 2014 09:40:08 +0200 Subject: add Windows 8.1 override Change-Id: Id8aa549e4ba5d8b550405823e26bb68da9403ced Reviewed-by: Oliver Wolff --- src/corelib/global/qglobal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index d7c166721e..6b5638d336 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1922,6 +1922,8 @@ QSysInfo::WinVersion QSysInfo::windowsVersion() winver = QSysInfo::WV_WINDOWS7; else if (override == "WINDOWS8") winver = QSysInfo::WV_WINDOWS8; + else if (override == "WINDOWS8_1") + winver = QSysInfo::WV_WINDOWS8_1; } #endif #endif // !Q_OS_WINRT -- cgit v1.2.3 From 6bd8c3742e111301481d3658a7c0a970bb10d66b Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Mon, 26 May 2014 18:26:45 -0300 Subject: QNX: Fix clearing transparent buffer Testing whether alphaBufferSize() != 0 does not work, because when no alpha channel is present, alphaBufferSize() can return '-1', which will cause non-transparent windows to be wrongly cleared and an artifact will appear. Change-Id: Id9e985f105c0bb302cc6f53960a5dbae2acdb921 Reviewed-by: Frank Osterfeld Reviewed-by: Wolfgang Bremer Reviewed-by: Sergio Ahumada --- src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp index 3109388fb2..e0ecb5c798 100644 --- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp @@ -170,7 +170,7 @@ void QQnxRasterBackingStore::beginPaint(const QRegion ®ion) platformWindow()->adjustBufferSize(); - if (window()->requestedFormat().alphaBufferSize() != 0) { + if (window()->requestedFormat().alphaBufferSize() > 0) { foreach (const QRect &r, region.rects()) { // Clear transparent regions const int bg[] = { -- cgit v1.2.3 From 69e2d3b3e96bb1fa553acb5cd867267d1596c314 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Thu, 29 May 2014 19:20:17 -0300 Subject: QNX: Fix compilation when OpenGL is not available Change-Id: I67a1d095fc3efd58e9520c9cb3fad13e04a4d64f Reviewed-by: Frank Osterfeld Reviewed-by: Bernd Weimer --- src/plugins/platforms/qnx/qqnxnativeinterface.cpp | 8 ++++++++ src/plugins/platforms/qnx/qqnxnativeinterface.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index a245a0c43a..05504f8bf4 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -41,7 +41,10 @@ #include "qqnxnativeinterface.h" +#if !defined(QT_NO_OPENGL) #include "qqnxglcontext.h" +#endif + #include "qqnxscreen.h" #include "qqnxwindow.h" #if defined(QQNX_IMF) @@ -50,7 +53,10 @@ #include "qqnxintegration.h" +#if !defined(QT_NO_OPENGL) #include +#endif + #include #include @@ -95,6 +101,7 @@ void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resour return 0; } +#if !defined(QT_NO_OPENGL) void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { if (resource == "eglcontext" && context) @@ -102,6 +109,7 @@ void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, return 0; } +#endif void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) { diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h index 83900791f6..41e6105f84 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.h +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h @@ -56,7 +56,10 @@ public: void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen); void *nativeResourceForIntegration(const QByteArray &resource); +#if !defined(QT_NO_OPENGL) void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); +#endif + void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource); -- cgit v1.2.3 From 6b9a9a01e289381ea915ac43595c6c5da0db73b4 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 23 May 2014 17:16:54 +0200 Subject: remove HSTRING instances HSTRING needs to be released or handles will be leaked. Instead use HString which takes care of resource management on its own. Task-Number: QTBUG-38115 Change-Id: I2c767776c1f22f45acd8dd77b693f30d63d894b9 Reviewed-by: Andrew Knight Reviewed-by: Oliver Wolff --- src/corelib/io/qfilesystemengine_win.cpp | 12 ++--- src/corelib/io/qsettings.cpp | 6 +-- src/corelib/io/qstandardpaths_winrt.cpp | 6 +-- src/corelib/tools/qlocale_win.cpp | 6 +-- src/network/kernel/qdnslookup_winrt.cpp | 12 ++--- src/network/kernel/qhostinfo_winrt.cpp | 24 +++++----- src/network/kernel/qnetworkinterface_winrt.cpp | 6 +-- src/network/socket/qnativesocketengine_winrt.cpp | 56 +++++++++++----------- .../winrt/qwinrtplatformmessagedialoghelper.cpp | 7 +-- src/plugins/platforms/winrt/qwinrtservices.cpp | 15 +++--- src/winmain/qtmain_winrt.cpp | 9 ++-- 11 files changed, 82 insertions(+), 77 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8e3bacd6b7..1d79136422 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1219,11 +1219,11 @@ QString QFileSystemEngine::rootPath() if (FAILED(installedLocation.As(&item))) return ret; - HSTRING finalWinPath; - if (FAILED(item->get_Path(&finalWinPath))) + HString finalWinPath; + if (FAILED(item->get_Path(finalWinPath.GetAddressOf()))) return ret; - ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(finalWinPath, nullptr))); + ret = QDir::fromNativeSeparators(QString::fromWCharArray(finalWinPath.GetRawBuffer(nullptr))); #else QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData()); @@ -1319,10 +1319,10 @@ QString QFileSystemEngine::tempPath() ComPtr tempFolderItem; if (FAILED(tempFolder.As(&tempFolderItem))) return ret; - HSTRING path; - if (FAILED(tempFolderItem->get_Path(&path))) + HString path; + if (FAILED(tempFolderItem->get_Path(path.GetAddressOf()))) return ret; - ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr))); + ret = QDir::fromNativeSeparators(QString::fromWCharArray(path.GetRawBuffer(nullptr))); #endif // Q_OS_WINRT if (ret.isEmpty()) { #if !defined(Q_OS_WINCE) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 63a0266948..7b4240e102 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1084,10 +1084,10 @@ static QString windowsConfigPath(int type) ComPtr localFolderItem; if (FAILED(localFolder.As(&localFolderItem))) return result; - HSTRING path; - if (FAILED(localFolderItem->get_Path(&path))) + HString path; + if (FAILED(localFolderItem->get_Path(path.GetAddressOf()))) return result; - result = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr)); + result = QString::fromWCharArray(path.GetRawBuffer(nullptr)); } switch (type) { diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp index bd72de11bb..84a3930ee0 100644 --- a/src/corelib/io/qstandardpaths_winrt.cpp +++ b/src/corelib/io/qstandardpaths_winrt.cpp @@ -89,10 +89,10 @@ QString QStandardPaths::writableLocation(StandardLocation type) ComPtr settingsFolderItem; if (FAILED(settingsFolder.As(&settingsFolderItem))) break; - HSTRING path; - if (FAILED(settingsFolderItem->get_Path(&path))) + HString path; + if (FAILED(settingsFolderItem->get_Path(path.GetAddressOf()))) break; - result = convertCharArray(WindowsGetStringRawBuffer(path, nullptr)); + result = convertCharArray(path.GetRawBuffer(nullptr)); if (isTestModeEnabled()) result += QLatin1String("/qttest"); break; diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index 1690dd83ee..4c44016fdf 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -663,10 +663,10 @@ QVariant QSystemLocalePrivate::uiLanguages() unsigned int size; languageList->get_Size(&size); for (unsigned int i = 0; i < size; ++i) { - HSTRING language; - languageList->GetAt(i, &language); + HString language; + languageList->GetAt(i, language.GetAddressOf()); UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(language, &length); + PCWSTR rawString = language.GetRawBuffer(&length); result << QString::fromWCharArray(rawString, length); } #else // !Q_OS_WINPHONE diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp index 6ac944934a..08f3167a29 100644 --- a/src/network/kernel/qdnslookup_winrt.cpp +++ b/src/network/kernel/qdnslookup_winrt.cpp @@ -98,9 +98,9 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); IAsyncOperation *> *op; - HSTRING proto; - WindowsCreateString(L"0", 1, &proto); - datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op); + datagramSocketStatics->GetEndpointPairsAsync(host, + HString::MakeReference(L"0").Get(), + &op); datagramSocketStatics->Release(); host->Release(); @@ -134,11 +134,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN || (type == HostNameType_Ipv6 && requestType == QDnsLookup::A)))) continue; - HSTRING name; - remoteHost->get_CanonicalName(&name); + HString name; + remoteHost->get_CanonicalName(name.GetAddressOf()); remoteHost->Release(); UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(name, &length); + PCWSTR rawString = name.GetRawBuffer(&length); QDnsHostAddressRecord record; record.d->name = aceHostname; record.d->value = QHostAddress(QString::fromWCharArray(rawString, length)); diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp index 92897f563d..e02cd98e08 100644 --- a/src/network/kernel/qhostinfo_winrt.cpp +++ b/src/network/kernel/qhostinfo_winrt.cpp @@ -95,9 +95,9 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); IAsyncOperation *> *op; - HSTRING proto; - WindowsCreateString(L"0", 1, &proto); - datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op); + datagramSocketStatics->GetEndpointPairsAsync(host, + HString::MakeReference(L"0").Get(), + &op); datagramSocketStatics->Release(); host->Release(); @@ -131,11 +131,11 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) if (type == HostNameType_DomainName) continue; - HSTRING name; - remoteHost->get_CanonicalName(&name); + HString name; + remoteHost->get_CanonicalName(name.GetAddressOf()); remoteHost->Release(); UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(name, &length); + PCWSTR rawString = name.GetRawBuffer(&length); QHostAddress addr; addr.setAddress(QString::fromWCharArray(rawString, length)); if (!addresses.contains(addr)) @@ -170,22 +170,22 @@ QString QHostInfo::localHostName() if (type != HostNameType_DomainName) continue; - HSTRING name; - hostName->get_CanonicalName(&name); + HString name; + hostName->get_CanonicalName(name.GetAddressOf()); hostName->Release(); UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(name, &length); + PCWSTR rawString = name.GetRawBuffer(&length); return QString::fromWCharArray(rawString, length); } IHostName *firstHost; hostNames->GetAt(0, &firstHost); hostNames->Release(); - HSTRING name; - firstHost->get_CanonicalName(&name); + HString name; + firstHost->get_CanonicalName(name.GetAddressOf()); firstHost->Release(); UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(name, &length); + PCWSTR rawString = name.GetRawBuffer(&length); return QString::fromWCharArray(rawString, length); } diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp index 6a814c85d4..48a96928a8 100644 --- a/src/network/kernel/qnetworkinterface_winrt.cpp +++ b/src/network/kernel/qnetworkinterface_winrt.cpp @@ -114,11 +114,11 @@ static QList interfaceListing() || (type == HostNameType_Ipv6 && hostInfo.prefixLength > 128)) continue; - HSTRING name; - hostName->get_CanonicalName(&name); + HString name; + hostName->get_CanonicalName(name.GetAddressOf()); hostName->Release(); UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(name, &length); + PCWSTR rawString = name.GetRawBuffer(&length); hostInfo.address = QString::fromWCharArray(rawString, length); hostList << hostInfo; diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index a32a757191..8eb632ff63 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -124,10 +124,10 @@ struct SocketHandler Q_GLOBAL_STATIC(SocketHandler, gSocketHandler) -QString qt_QStringFromHSTRING(HSTRING string) +static inline QString qt_QStringFromHString(const HString &string) { UINT32 length; - PCWSTR rawString = WindowsGetStringRawBuffer(string, &length); + PCWSTR rawString = string.GetRawBuffer(&length); return QString::fromWCharArray(rawString, length); } @@ -604,13 +604,13 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress for (int i = 0; i < d->pendingDatagrams.size(); ++i) { IDatagramSocketMessageReceivedEventArgs *arg = d->pendingDatagrams.at(i); ComPtr remoteHost; - HSTRING remoteHostString; - HSTRING remotePort; + HString remoteHostString; + HString remotePort; arg->get_RemoteAddress(&remoteHost); - arg->get_RemotePort(&remotePort); - remoteHost->get_CanonicalName(&remoteHostString); - returnAddress.setAddress(qt_QStringFromHSTRING(remoteHostString)); - returnPort = qt_QStringFromHSTRING(remotePort).toInt(); + arg->get_RemotePort(remotePort.GetAddressOf()); + remoteHost->get_CanonicalName(remoteHostString.GetAddressOf()); + returnAddress.setAddress(qt_QStringFromHString(remoteHostString)); + returnPort = qt_QStringFromHString(remotePort).toInt(); ComPtr reader; arg->GetDataReader(&reader); if (!reader) @@ -1097,7 +1097,7 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() if (socketType == QAbstractSocket::TcpSocket) { ComPtr hostName; - HSTRING tmpHString; + HString tmpHString; ComPtr info; if (FAILED(tcp->get_Information(&info))) { qWarning("QNativeSocketEnginePrivate::fetchConnectionParameters: Could not obtain socket info"); @@ -1105,28 +1105,28 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } info->get_LocalAddress(&hostName); if (hostName) { - hostName->get_CanonicalName(&tmpHString); - localAddress.setAddress(qt_QStringFromHSTRING(tmpHString)); - info->get_LocalPort(&tmpHString); - localPort = qt_QStringFromHSTRING(tmpHString).toInt(); + hostName->get_CanonicalName(tmpHString.GetAddressOf()); + localAddress.setAddress(qt_QStringFromHString(tmpHString)); + info->get_LocalPort(tmpHString.GetAddressOf()); + localPort = qt_QStringFromHString(tmpHString).toInt(); } if (!localPort && tcpListener) { ComPtr listenerInfo = 0; tcpListener->get_Information(&listenerInfo); - listenerInfo->get_LocalPort(&tmpHString); - localPort = qt_QStringFromHSTRING(tmpHString).toInt(); + listenerInfo->get_LocalPort(tmpHString.GetAddressOf()); + localPort = qt_QStringFromHString(tmpHString).toInt(); localAddress == QHostAddress::Any; } info->get_RemoteAddress(&hostName); if (hostName) { - hostName->get_CanonicalName(&tmpHString); - peerAddress.setAddress(qt_QStringFromHSTRING(tmpHString)); - info->get_RemotePort(&tmpHString); - peerPort = qt_QStringFromHSTRING(tmpHString).toInt(); + hostName->get_CanonicalName(tmpHString.GetAddressOf()); + peerAddress.setAddress(qt_QStringFromHString(tmpHString)); + info->get_RemotePort(tmpHString.GetAddressOf()); + peerPort = qt_QStringFromHString(tmpHString).toInt(); } } else if (socketType == QAbstractSocket::UdpSocket) { ComPtr hostName; - HSTRING tmpHString; + HString tmpHString; ComPtr info; if (FAILED(udp->get_Information(&info))) { qWarning("QNativeSocketEnginePrivate::fetchConnectionParameters: Could not obtain socket information"); @@ -1134,18 +1134,18 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } info->get_LocalAddress(&hostName); if (hostName) { - hostName->get_CanonicalName(&tmpHString); - localAddress.setAddress(qt_QStringFromHSTRING(tmpHString)); - info->get_LocalPort(&tmpHString); - localPort = qt_QStringFromHSTRING(tmpHString).toInt(); + hostName->get_CanonicalName(tmpHString.GetAddressOf()); + localAddress.setAddress(qt_QStringFromHString(tmpHString)); + info->get_LocalPort(tmpHString.GetAddressOf()); + localPort = qt_QStringFromHString(tmpHString).toInt(); } info->get_RemoteAddress(&hostName); if (hostName) { - hostName->get_CanonicalName(&tmpHString); - peerAddress.setAddress(qt_QStringFromHSTRING(tmpHString)); - info->get_RemotePort(&tmpHString); - peerPort = qt_QStringFromHSTRING(tmpHString).toInt(); + hostName->get_CanonicalName(tmpHString.GetAddressOf()); + peerAddress.setAddress(qt_QStringFromHString(tmpHString)); + info->get_RemotePort(tmpHString.GetAddressOf()); + peerPort = qt_QStringFromHString(tmpHString).toInt(); } } return true; diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp index e70d06860c..c2f884055d 100644 --- a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp +++ b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp @@ -171,10 +171,11 @@ void QWinRTPlatformMessageDialogHelper::hide() HRESULT QWinRTPlatformMessageDialogHelper::onInvoked(ABI::Windows::UI::Popups::IUICommand *command) { - HSTRING hLabel; + HString hLabel; UINT32 labelLength; - command->get_Label(&hLabel); - QString label = QString::fromWCharArray(::WindowsGetStringRawBuffer(hLabel, &labelLength)); + command->get_Label(hLabel.GetAddressOf()); + PCWSTR rawString = hLabel.GetRawBuffer(&labelLength); + QString label = QString::fromWCharArray(rawString, labelLength); int buttonId = -1; for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) { if ( options()->standardButtons() & i ) { diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp index 73c090351b..b0f9247d36 100644 --- a/src/plugins/platforms/winrt/qwinrtservices.cpp +++ b/src/plugins/platforms/winrt/qwinrtservices.cpp @@ -81,9 +81,11 @@ bool QWinRTServices::openUrl(const QUrl &url) return QPlatformServices::openUrl(url); IUriRuntimeClass *uri; - QString urlString = url.toString(); HSTRING uriString; HSTRING_HEADER header; - WindowsCreateStringReference((const wchar_t*)urlString.utf16(), urlString.length(), &header, &uriString); - m_uriFactory->CreateUri(uriString, &uri); + QString urlString = url.toString(); + // ### TODO: Replace with HStringReference when WP8.0 support is removed + HString uriString; + uriString.Set((const wchar_t*)urlString.utf16(), urlString.length()); + m_uriFactory->CreateUri(uriString.Get(), &uri); if (!uri) return false; @@ -107,10 +109,11 @@ bool QWinRTServices::openDocument(const QUrl &url) return QPlatformServices::openDocument(url); const QString pathString = QDir::toNativeSeparators(url.toLocalFile()); - HSTRING_HEADER header; HSTRING path; - WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path); + // ### TODO: Replace with HStringReference when WP8.0 support is removed + HString path; + path.Set((const wchar_t*)pathString.utf16(), pathString.length()); IAsyncOperation *fileOp; - m_fileFactory->GetFileFromPathAsync(path, &fileOp); + m_fileFactory->GetFileFromPathAsync(path.Get(), &fileOp); if (!fileOp) return false; diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index eef23130f9..bcb3445bcd 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -74,6 +74,7 @@ extern "C" { using namespace ABI::Windows::ApplicationModel; using namespace ABI::Windows::Foundation; using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; #define qHString(x) Wrappers::HString::MakeReference(x).Get() #define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication @@ -186,11 +187,11 @@ private: for (int i = m_argc; i < m_argv.size(); ++i) delete[] m_argv[i]; m_argv.resize(m_argc); - HSTRING arguments; - launchArgs->get_Arguments(&arguments); - if (arguments) { + HString arguments; + launchArgs->get_Arguments(arguments.GetAddressOf()); + if (arguments.IsValid()) { foreach (const QByteArray &arg, QString::fromWCharArray( - WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) { + arguments.GetRawBuffer(nullptr)).toLocal8Bit().split(' ')) { m_argv.append(qstrdup(arg.constData())); } } -- cgit v1.2.3 From 35edf22dc30986f8ed9b0faa48bd37c43f12da88 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 3 Jun 2014 10:39:30 +0300 Subject: Fix VCLibs dependency in WP8.1 manifest CRT dependencies should contain "Phone" in the name. Change-Id: I1b0de01df6a016c20b59232f6068e9bb87e3f18c Reviewed-by: Oliver Wolff Reviewed-by: Maurice Kalinowski --- mkspecs/features/winrt/package_manifest.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 85a6485535..46fe1e57e4 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -61,6 +61,7 @@ # Provide the C-runtime dependency equals(TEMPLATE, "app") { VCLIBS = Microsoft.VCLibs.$$replace(MSVC_VER, \\., ).00 + winphone: VCLIBS = $${VCLIBS}.Phone CONFIG(debug, debug|release): \ WINRT_MANIFEST.dependencies += $${VCLIBS}.Debug else: \ -- cgit v1.2.3 From ce6c0d2e61f70d6175b763348e0860133dd4f54f Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 6 May 2014 11:23:09 +0200 Subject: QNX: Fix tst_qfilesystemwatcher If QNX does not have inotify there is no native engine. Change-Id: I042efd0b59f916f9e0b55bbe5c7f3fe7bb6914c8 Reviewed-by: Friedemann Kleint Reviewed-by: Sergio Ahumada Reviewed-by: Fabian Bumberger --- tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 4f7ddce9c3..e06af5a799 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -112,9 +112,11 @@ void tst_QFileSystemWatcher::basicTest_data() + QChar(ushort(0x00DC)) // LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS + QStringLiteral(".txt"); +#if !defined(Q_OS_QNX) || !defined(QT_NO_INOTIFY) QTest::newRow("native backend-testfile") << "native" << testFile; - QTest::newRow("poller backend-testfile") << "poller" << testFile; QTest::newRow("native backend-specialchars") << "native" << specialCharacterFile; +#endif + QTest::newRow("poller backend-testfile") << "poller" << testFile; } void tst_QFileSystemWatcher::basicTest() -- cgit v1.2.3 From 365cd4adeb7c8719d438ff2438c1db5726c90c54 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Mon, 2 Jun 2014 17:12:37 -0300 Subject: QNX: fix race condition when clearing transparent buffer Block flush until all bits have been flushed. This prevents Qt from trying to draw over the buffer while it is still being cleared. Change-Id: I49b90a7653ec3768411a1a94837bb31fec4d44e8 Reviewed-by: Frank Osterfeld Reviewed-by: Andreas Holzammer Reviewed-by: Bernd Weimer --- src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp index e0ecb5c798..7ae042cb50 100644 --- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp @@ -185,8 +185,8 @@ void QQnxRasterBackingStore::beginPaint(const QRegion ®ion) platformWindow()->renderBuffer().nativeBuffer(), bg), "failed to clear transparent regions"); } - Q_SCREEN_CHECKERROR(screen_flush_blits(platformWindow()->screen()->nativeContext(), 0), - "failed to flush blits"); + Q_SCREEN_CHECKERROR(screen_flush_blits(platformWindow()->screen()->nativeContext(), + SCREEN_WAIT_IDLE), "failed to flush blits"); } } -- cgit v1.2.3 From 9e02f9cf085386f44045e5991a39c05acb660b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 15 May 2014 23:14:58 +0200 Subject: Cocoa: Make QMacNativeWidget event processing work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't interrupt the Qt event loop if the Qt event loop isn't running (meaning processEvents has not/ will not be called). This can happen in the QMacNativeWidget or plugin case where the native code calls [NSApp run] and QApplication::exec() is never called. In Qt 4 this was not necessary since UI event processing was more direct: QCocoaView would call QCoreApplication::sendMouseEvent/sendSpontaneousEvent directly on mouse events. Task-number: QTBUG-36225 Change-Id: I2894cbbca66a902652c9f8bc916e94ad8ce0e18e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 9aaf08adcf..45c0714b6b 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -870,7 +870,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() return; } - if (interrupt) { + if (processEventsCalled > 0 && interrupt) { if (currentExecIsNSAppRun) { // The event dispatcher has been interrupted. But since // [NSApplication run] is running the event loop, we -- cgit v1.2.3 From 70e4428b6f1c6a4bad112203f67ee7d22107616c Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 3 Jun 2014 14:20:20 +0200 Subject: Cocoa: Adapt to Xcode 6 clang version sudden pickiness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Yes, that means OS X Yosemite fix. Change-Id: I236f7af7b803de24ff0895e04c9a9253b5cfdb3b Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 2 +- src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 2 +- src/plugins/platforms/cocoa/qcocoamenuloader.mm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index dd3b9f53db..078dc67cad 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -380,7 +380,7 @@ - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); if (!iface) - return nil; + return NO; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { return iface->state().focusable ? YES : NO; diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index f8411845dc..548c6a23f0 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -124,7 +124,7 @@ static void cleanupCocoaApplicationDelegate() [dockMenu release]; [qtMenuLoader release]; if (reflectionDelegate) { - [NSApp setDelegate:reflectionDelegate]; + [[NSApplication sharedApplication] setDelegate:reflectionDelegate]; [reflectionDelegate release]; } [[NSNotificationCenter defaultCenter] removeObserver:self]; diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 60bc3b5a55..9340e945fb 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -174,7 +174,7 @@ QT_END_NAMESPACE - (void)removeActionsFromAppMenu { for (NSMenuItem *item in [appMenu itemArray]) - [item setTag:nil]; + [item setTag:0]; } - (void)dealloc -- cgit v1.2.3 From ac7bf97f51837eecc5e5570d5d62996746f378ed Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Thu, 22 May 2014 15:19:46 -0700 Subject: Cocoa: clear queued user input events when window is destroyed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QCocoaEventDispatcher stores user input events in a queue in certain cases. If the target of those events is destroyed, the events are later sent to the stale window, causing a crash. Task-number: QTBUG-39211 Change-Id: Ie55d2df5697c742bcb644ebf8c5028015a0b8148 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 2 ++ src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 15 +++++++++++++++ src/plugins/platforms/cocoa/qcocoawindow.mm | 10 +++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 33d7dcbcf4..dc0b8fcc18 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -178,6 +178,8 @@ public: void maybeCancelWaitForMoreEvents(); void ensureNSAppInitialized(); + void removeQueuedUserInputEvents(int nsWinNumber); + QCFSocketNotifier cfSocketNotifier; QList queuedUserInputEvents; // NSEvent * CFRunLoopSourceRef postedEventsSource; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 45c0714b6b..e7f8992c6d 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -892,6 +892,21 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() } } +void QCocoaEventDispatcherPrivate::removeQueuedUserInputEvents(int nsWinNumber) +{ + if (nsWinNumber) { + int eventIndex = queuedUserInputEvents.size(); + + while (--eventIndex >= 0) { + NSEvent * nsevent = static_cast(queuedUserInputEvents.at(eventIndex)); + if ([nsevent windowNumber] == nsWinNumber) { + queuedUserInputEvents.removeAt(eventIndex); + [nsevent release]; + } + } + } +} + void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 7ab7486ce9..c8ca494b33 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -189,7 +189,15 @@ static bool isMouseEvent(NSEvent *ev) - (void)clearWindow { - _window = nil; + if (_window) { + QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast(QGuiApplication::instance()->eventDispatcher()); + if (cocoaEventDispatcher) { + QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast(QObjectPrivate::get(cocoaEventDispatcher)); + cocoaEventDispatcherPrivate->removeQueuedUserInputEvents([_window windowNumber]); + } + + _window = nil; + } } - (void)dealloc -- cgit v1.2.3 From 90808ead98edbab33a6bcc724d123864842a5ed3 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 22 May 2014 14:10:53 +0200 Subject: Android: Fix flashing on startup/shutdown There were several issues on startup of the application which were caused by the fact that we would get the wrong available screen geometry on startup, set this as the initial surface size and then expose native windows with this size. This would cause first a flicker of white on the early expose and the window contents to jump around as the window was resized to the actual available space on screen. The fix for this is to postpone the first expose until we have actually got a proper screen size from the main layout. We use width,height = 0 as an indicator that the available geometry is not yet known, and we skip posting any expose events before this is set by the layout. In addition, since we removed the surface before we shut down the application, it was by a white rectangle before the shutdown transition happens, and this white rectangle will be animated instead of application contents. To rectify this, we make sure the last surface in the stack remains in the layout until it is either replaced by a different surface or until the application has shut down. This way, the shutdown animation will work on this surface instead. [ChangeLog][Android] Fixed regression where there would be flickering on startup and shutdown of the application. Task-number: QTBUG-38960 Change-Id: Ia1579ca8c522d8beeab066f78070ad49009d0238 Reviewed-by: Paul Olav Tvete --- .../qtproject/qt5/android/QtActivityDelegate.java | 33 ++++++++++++++++++---- .../qtproject/qt5/android/bindings/QtActivity.java | 3 ++ src/plugins/platforms/android/androidjnimain.cpp | 7 +++-- .../android/qandroidplatformopenglwindow.cpp | 24 ++++++++++++++-- .../platforms/android/qandroidplatformscreen.cpp | 15 ++++++++++ .../platforms/android/qandroidplatformwindow.cpp | 4 ++- 6 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 554c54d4a0..c39bd1a749 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -118,6 +118,7 @@ public class QtActivityDelegate private InputMethodManager m_imm = null; private boolean m_quitApp = true; private Process m_debuggerProcess = null; // debugger process + private View m_dummyView = null; private boolean m_keyboardIsVisible = false; public boolean m_backKeyPressedSent = false; @@ -667,7 +668,7 @@ public class QtActivityDelegate DisplayMetrics metrics = new DisplayMetrics(); m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); QtNative.setApplicationDisplayMetrics(metrics.widthPixels, metrics.heightPixels, - metrics.widthPixels, metrics.heightPixels, + 0, 0, metrics.xdpi, metrics.ydpi, metrics.scaledDensity); } m_layout = new QtLayout(m_activity); @@ -677,6 +678,10 @@ public class QtActivityDelegate m_nativeViews = new HashMap(); m_activity.registerForContextMenu(m_layout); + m_activity.setContentView(m_layout, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + int orientation = m_activity.getResources().getConfiguration().orientation; int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation(); boolean rot90 = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270); @@ -1001,6 +1006,11 @@ public class QtActivityDelegate } public void insertNativeView(int id, View view, int x, int y, int w, int h) { + if (m_dummyView != null) { + m_layout.removeView(m_dummyView); + m_dummyView = null; + } + if (m_nativeViews.containsKey(id)) m_layout.removeView(m_nativeViews.remove(id)); @@ -1026,9 +1036,10 @@ public class QtActivityDelegate m_activity.getWindow().setBackgroundDrawable(m_activity.getResources().getDrawable(attr.resourceId)); } - m_activity.setContentView(m_layout, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); + if (m_dummyView != null) { + m_layout.removeView(m_dummyView); + m_dummyView = null; + } } if (m_surfaces.containsKey(id)) @@ -1065,12 +1076,22 @@ public class QtActivityDelegate } public void destroySurface(int id) { + View view = null; + if (m_surfaces.containsKey(id)) { - m_layout.removeView(m_surfaces.remove(id)); + view = m_surfaces.remove(id); } else if (m_nativeViews.containsKey(id)) { - m_layout.removeView(m_nativeViews.remove(id)); + view = m_nativeViews.remove(id); } else { Log.e(QtNative.QtTAG, "Surface " + id +" not found!"); } + + // Keep last frame in stack until it is replaced to get correct + // shutdown transition + if (m_surfaces.size() == 0 && m_nativeViews.size() == 0) { + m_dummyView = view; + } else if (view != null) { + m_layout.removeView(view); + } } } diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index f99bb84077..45be15bc01 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -69,6 +69,7 @@ import android.content.res.Resources.Theme; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -874,6 +875,8 @@ public class QtActivity extends Activity // if splash screen is defined, then show it if (m_activityInfo.metaData.containsKey("android.app.splash_screen_drawable")) getWindow().setBackgroundDrawableResource(m_activityInfo.metaData.getInt("android.app.splash_screen_drawable")); + else + getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000)); startApp(true); } } diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 7ca4db710b..d484a2faff 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -573,8 +573,11 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/) return; if (QGuiApplication::instance() != 0) { - foreach (QWindow *w, QGuiApplication::topLevelWindows()) - QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry())); + foreach (QWindow *w, QGuiApplication::topLevelWindows()) { + QRect availableGeometry = w->screen()->availableGeometry(); + if (w->geometry().width() > 0 && w->geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) + QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry())); + } } QAndroidPlatformScreen *screen = static_cast(m_androidPlatformIntegration->screen()); diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp index 34db729289..5a028e8a5b 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp @@ -47,7 +47,8 @@ #include #include - +#include +#include #include #include @@ -77,8 +78,20 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect) if (rect == geometry()) return; + QRect oldGeometry = geometry(); + QAndroidPlatformWindow::setGeometry(rect); QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect); + + QRect availableGeometry = screen()->availableGeometry(); + if (oldGeometry.width() == 0 + && oldGeometry.height() == 0 + && rect.width() > 0 + && rect.height() > 0 + && availableGeometry.width() > 0 + && availableGeometry.height() > 0) { + QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect)); + } } EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config) @@ -100,8 +113,11 @@ void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config) createEgl(config); + // we've create another surface, the window should be repainted - QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); + QRect availableGeometry = screen()->availableGeometry(); + if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); } void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config) @@ -143,7 +159,9 @@ void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surfac unlockSurface(); // repaint the window - QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); + QRect availableGeometry = screen()->availableGeometry(); + if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 678f4e6b5a..11472ce1da 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -55,6 +55,9 @@ #include #include +#include +#include + QT_BEGIN_NAMESPACE #ifdef QANDROIDPLATFORMSCREEN_DEBUG @@ -217,11 +220,23 @@ void QAndroidPlatformScreen::setGeometry(const QRect &rect) if (m_geometry == rect) return; + QRect oldGeometry = m_geometry; + m_geometry = rect; QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry()); resizeMaximizedWindows(); + if (oldGeometry.width() == 0 && oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0) { + QList windows = QGuiApplication::allWindows(); + for (int i = 0; i < windows.size(); ++i) { + QWindow *w = windows.at(i); + QRect geometry = w->handle()->geometry(); + if (geometry.width() > 0 && geometry.height() > 0) + QWindowSystemInterface::handleExposeEvent(w, QRegion(geometry)); + } + } + if (m_id != -1) { if (m_nativeSurface) { ANativeWindow_release(m_nativeSurface); diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index b4231f0283..558525b78c 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -88,7 +88,9 @@ void QAndroidPlatformWindow::setVisible(bool visible) setGeometry(platformScreen()->availableGeometry()); } - QPlatformWindow::setVisible(visible); + QRect availableGeometry = screen()->availableGeometry(); + if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) + QPlatformWindow::setVisible(visible); if (visible) platformScreen()->addWindow(this); -- cgit v1.2.3 From 80b6fbc2d9dfc753d6570e971aa4cf4f3420585c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 21 May 2014 16:30:50 +0200 Subject: Android: Support offscreen surfaces on pbuffers This is pretty much the same thing that eglfs does. Task-number: QTBUG-38960 Change-Id: Ibf310ca8e3a4e31e5310ab3a3d3e851eae31a4ad Reviewed-by: Laszlo Agocs --- .../platforms/android/qandroidplatformintegration.cpp | 14 ++++++++++++++ .../platforms/android/qandroidplatformintegration.h | 1 + .../platforms/android/qandroidplatformopenglcontext.cpp | 5 ++++- .../platforms/android/qandroidplatformopenglwindow.cpp | 9 +++++++++ .../platforms/android/qandroidplatformopenglwindow.h | 2 ++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 7f0f40be0f..213b1bb7e6 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -45,11 +45,14 @@ #include #include #include +#include #include +#include #include #include +#include #include "androidjnimain.h" #include "qabstracteventdispatcher.h" @@ -207,6 +210,17 @@ QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext return new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay); } +QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const +{ + QSurfaceFormat format(surface->requestedFormat()); + format.setAlphaBufferSize(8); + format.setRedBufferSize(8); + format.setGreenBufferSize(8); + format.setBlueBufferSize(8); + + return new QEGLPbuffer(m_eglDisplay, format, surface); +} + QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const { if (window->type() == Qt::ForeignWindow) diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index 4a3fe6c766..f8fa1a91dd 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -82,6 +82,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QAbstractEventDispatcher *createEventDispatcher() const; QAndroidPlatformScreen *screen() { return m_primaryScreen; } + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const; virtual void setDesktopSize(int width, int height); virtual void setDisplayMetrics(int width, int height); diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp index 152a06c99d..53047585cf 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp @@ -44,6 +44,8 @@ #include "qandroidplatformopenglwindow.h" #include "qandroidplatformintegration.h" +#include + #include #include @@ -98,7 +100,8 @@ EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatform { if (surface->surface()->surfaceClass() == QSurface::Window) return static_cast(surface)->eglSurface(eglConfig()); - return EGL_NO_SURFACE; + else + return static_cast(surface)->pbuffer(); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp index 5a028e8a5b..f0c4a1de2a 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp @@ -127,6 +127,7 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config) m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object()); m_androidSurfaceObject = QJNIObjectPrivate(); m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL); + m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat()); if (m_eglSurface == EGL_NO_SURFACE) { EGLint error = eglGetError(); eglTerminate(m_eglDisplay); @@ -134,6 +135,14 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config) } } +QSurfaceFormat QAndroidPlatformOpenGLWindow::format() const +{ + if (m_nativeWindow == 0) + return window()->requestedFormat(); + else + return m_format; +} + void QAndroidPlatformOpenGLWindow::clearEgl() { eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h index 7af8b722aa..83df15a524 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.h +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h @@ -60,6 +60,7 @@ public: void setGeometry(const QRect &rect); EGLSurface eglSurface(EGLConfig config); + QSurfaceFormat format() const; void checkNativeSurface(EGLConfig config); @@ -76,6 +77,7 @@ private: int m_nativeSurfaceId = -1; QJNIObjectPrivate m_androidSurfaceObject; QWaitCondition m_surfaceWaitCondition; + QSurfaceFormat m_format; }; QT_END_NAMESPACE -- cgit v1.2.3 From 91b0b2e1a7566dda00ec24e674784e4ccc99fea6 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 4 Jun 2014 12:37:19 +0200 Subject: Android: Repaint affected areas when window moves There are no automatic updates of the window when it moves, since this is not required on most platforms. This broke drag and drop on Android, because drag and drop creates a temporary window containing a pixmap with a snapshot of its content. We need to make sure the old and new location of the window is repainted when it has moved. [ChangeLog][Android] Fixed repaint issues in drag and drop. Task-number: QTBUG-35975 Change-Id: I7b043d728551d9963fb5acec804fb90aec5b50ff Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/qandroidplatformrasterwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp index eb5a73c4a3..3fb236793b 100644 --- a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp @@ -76,6 +76,8 @@ void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect) { m_oldGeometry = geometry(); QAndroidPlatformWindow::setGeometry(rect); + if (rect.topLeft() != m_oldGeometry.topLeft()) + repaint(QRegion(rect)); } QT_END_NAMESPACE -- cgit v1.2.3 From a149d2f73ec45084c589ef4211974ba50c0d4631 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 4 Jun 2014 13:42:00 +0200 Subject: Do not clear default button in QMessageBox::setDetailedText(). Store the value of QMessageBoxPrivate::autoAddOkButton temporarily when automatically adding the "Show Details..." button. Task-number: QTBUG-39334 Change-Id: I173c83893548ee83b3d8ea2743f87686c32657e7 Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qmessagebox.cpp | 2 ++ tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index dcddc693c8..3350a926f0 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -2565,8 +2565,10 @@ void QMessageBox::setDetailedText(const QString &text) d->detailsText->hide(); } if (!d->detailsButton) { + const bool autoAddOkButton = d->autoAddOkButton; // QTBUG-39334, addButton() clears the flag. d->detailsButton = new DetailButton(this); addButton(d->detailsButton, QMessageBox::ActionRole); + d->autoAddOkButton = autoAddOkButton; } d->detailsText->setText(text); } diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 0425db3098..f9abd50a15 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -593,6 +593,11 @@ void tst_QMessageBox::detailsText() QString text("This is the details text."); box.setDetailedText(text); QCOMPARE(box.detailedText(), text); + box.show(); + QTest::qWaitForWindowExposed(&box); + // QTBUG-39334, the box should now have the default "Ok" button as well as + // the "Show Details.." button. + QCOMPARE(box.findChildren().size(), 2); } void tst_QMessageBox::detailsButtonText() -- cgit v1.2.3 From 7df8b1ada4b23acedda5724b492c26a8e322648b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 4 Jun 2014 13:52:37 +0200 Subject: Properly escape bytearray data outside the ascii range when using a codec Some codecs can't handle the range outside ascii properly and would then fail to read the data back in correctly. Task-number: QTBUG-15543 Change-Id: I4c02921e787a939eeec0c7a11603b5896d756aef Reviewed-by: Thiago Macieira --- src/corelib/io/qsettings.cpp | 7 +++++-- tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 7b4240e102..1748170324 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -696,6 +696,9 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, { bool needsQuotes = false; bool escapeNextIfDigit = false; + bool useCodec = codec && !str.startsWith(QLatin1String("@ByteArray(")) + && !str.startsWith(QLatin1String("@Variant(")); + int i; int startPos = result.size(); @@ -748,12 +751,12 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, result += (char)ch; break; default: - if (ch <= 0x1F || (ch >= 0x7F && !codec)) { + if (ch <= 0x1F || (ch >= 0x7F && !useCodec)) { result += "\\x"; result += QByteArray::number(ch, 16); escapeNextIfDigit = true; #ifndef QT_NO_TEXTCODEC - } else if (codec) { + } else if (useCodec) { // slow result += codec->fromUnicode(str.at(i)); #endif diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 501ad6f415..2c9868cd10 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -166,6 +166,7 @@ private slots: void testByteArray_data(); void testByteArray(); + void iniCodec(); private: const bool m_canWriteNativeSystemSettings; @@ -695,6 +696,28 @@ void tst_QSettings::testByteArray() } } +void tst_QSettings::iniCodec() +{ + { + QSettings settings("QtProject", "tst_qsettings"); + settings.setIniCodec("cp1251"); + QByteArray ba; + ba.resize(256); + for (int i = 0; i < ba.size(); i++) + ba[i] = i; + settings.setValue("array",ba); + } + { + QSettings settings("QtProject", "tst_qsettings"); + settings.setIniCodec("cp1251"); + QByteArray ba = settings.value("array").toByteArray(); + QCOMPARE(ba.size(), 256); + for (int i = 0; i < ba.size(); i++) + QCOMPARE((uchar)ba.at(i), (uchar)i); + } + +} + void tst_QSettings::testErrorHandling_data() { QTest::addColumn("filePerms"); // -1 means file should not exist -- cgit v1.2.3 From 958a4c9087e03502d0173735df4611a7f96a0463 Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Thu, 14 Nov 2013 13:56:19 +0100 Subject: QApp: Method to check for native style usage. Adds QApplicationPrivate::usesNativeStyle to check whether the QApplication is using the native platform style. This can be needed internally to decided whether to let the platform plugins do stuff or do it interally, style dependent. E.g. letting the platform plugin popup a QMenu vs. letting the style draw one. Change-Id: Ibb5e11a4d9d1d2824685ff146786a9354ceef43c Reviewed-by: BogDan Vatra --- src/widgets/kernel/qapplication.cpp | 21 +++++++++++++++++++++ src/widgets/kernel/qapplication_p.h | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index b4c4ffe7c7..0b983e7a9d 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -146,6 +146,20 @@ static void clearSystemPalette() QApplicationPrivate::sys_pal = 0; } +static QByteArray get_style_class_name() +{ + QScopedPointer s(QStyleFactory::create(QApplicationPrivate::desktopStyleKey())); + if (!s.isNull()) + return s->metaObject()->className(); + return QByteArray(); +} + +static QByteArray nativeStyleClassName() +{ + static QByteArray name = get_style_class_name(); + return name; +} + #ifdef Q_OS_WINCE int QApplicationPrivate::autoMaximizeThreshold = -1; bool QApplicationPrivate::autoSipEnabled = false; @@ -372,6 +386,8 @@ void qt_init_tooltip_palette(); void qt_cleanup(); QStyle *QApplicationPrivate::app_style = 0; // default application style +bool QApplicationPrivate::overrides_native_style = false; // whether native QApplication style is + // overridden, i.e. not native QString QApplicationPrivate::styleOverride; // style override #ifndef QT_NO_STYLE_STYLESHEET @@ -997,6 +1013,8 @@ QStyle *QApplication::style() Q_ASSERT(!"No styles available!"); return 0; } + QApplicationPrivate::overrides_native_style = + app_style->objectName() != QApplicationPrivate::desktopStyleKey(); } // take ownership of the style QApplicationPrivate::app_style->setParent(qApp); @@ -1061,6 +1079,9 @@ void QApplication::setStyle(QStyle *style) QStyle *old = QApplicationPrivate::app_style; // save + QApplicationPrivate::overrides_native_style = + nativeStyleClassName() == QByteArray(style->metaObject()->className()); + #ifndef QT_NO_STYLE_STYLESHEET if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast(style)) { // we have a stylesheet already and a new style is being set diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 0284a613d4..d5efb62dda 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -150,6 +150,12 @@ public: bool canQuit(); #endif + //style + static bool usesNativeStyle() + { + return !overrides_native_style; + } + bool notify_helper(QObject *receiver, QEvent * e); void construct( @@ -184,6 +190,7 @@ public: static QSize app_strut; static QWidgetList *popupWidgets; static QStyle *app_style; + static bool overrides_native_style; static int app_cspec; static QPalette *sys_pal; static QPalette *set_pal; -- cgit v1.2.3 From 8636bade176d692672f191bbfb8ded8bbb6aa88c Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 23 May 2014 20:22:02 +0200 Subject: qfreelist: fix data race on v[at].next Detected by clang's -fsanitize=thread in tst_qcoreapplication. Task-number: QTBUG-39024 Change-Id: I60b7cece0384f89dc62ac5128faf39a4084e72e2 Reviewed-by: Olivier Goffart --- src/corelib/tools/qfreelist_p.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 69b7fc67a0..ca946cbd8a 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -73,7 +73,7 @@ struct QFreeListElement typedef T &ReferenceType; T _t; - int next; + QAtomicInt next; inline ConstReferenceType t() const { return _t; } inline ReferenceType t() { return _t; } @@ -90,7 +90,7 @@ struct QFreeListElement typedef void ConstReferenceType; typedef void ReferenceType; - int next; + QAtomicInt next; inline void t() const { } inline void t() { } @@ -172,7 +172,7 @@ class QFreeList // qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset); ElementType *v = new ElementType[size]; for (int i = 0; i < size; ++i) - v[i].next = offset + i + 1; + v[i].next.store(offset + i + 1); return v; } @@ -254,7 +254,7 @@ inline int QFreeList::next() } } - newid = v[at].next | (id & ~ConstantsType::IndexMask); + newid = v[at].next.load() | (id & ~ConstantsType::IndexMask); } while (!_next.testAndSetRelaxed(id, newid)); // qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)", // id & ConstantsType::IndexMask, @@ -273,7 +273,7 @@ inline void QFreeList::release(int id) int x, newid; do { x = _next.loadAcquire(); - v[at].next = x & ConstantsType::IndexMask; + v[at].next.store(x & ConstantsType::IndexMask); newid = incrementserial(x, id); } while (!_next.testAndSetRelease(x, newid)); -- cgit v1.2.3 From d6525a6c1011bfec337d9403ab8cb5724dc8fdfb Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 4 Jun 2014 11:31:53 +0200 Subject: Doc: Fix undefined variable in QMetaMethod::invoke() documentation Task-number: QTBUG-38871 Change-Id: I5b7aef58c652d13110aa73b7856927b5ba6fea50 Reviewed-by: Olivier Goffart --- src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp index c0675d6cf0..708cacdf6e 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp @@ -124,7 +124,7 @@ QMetaMethod::invoke: Unable to handle unregistered datatype 'MyType' QString retVal; QByteArray normalizedSignature = QMetaObject::normalizedSignature("compute(QString, int, double)"); int methodIndex = obj->metaObject()->indexOfMethod(normalizedSignature); -QMetaMethod method = metaObject->method(methodIndex); +QMetaMethod method = obj->metaObject()->method(methodIndex); method.invoke(obj, Qt::DirectConnection, Q_RETURN_ARG(QString, retVal), -- cgit v1.2.3 From 020c54daaaee6a0e4ce7de9bdf57b3ca4e8965b1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 12 May 2014 15:30:47 +0200 Subject: fix/optimize QT_PLUGIN_PATH construction in qtAddTargetEnv() instead of adding all possible plugin paths (for which QMAKEMODULES wouldn't have been a reliable source anyway), only add the paths of plugins of the necessary types. this necessitates that we create qt_plugin_.pri files also in shared builds of qt when making a prefix build. we don't install them unless it's a static build, though. Change-Id: Ib56b009562a7131d4dc4dfc259b34ec6581b0f77 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_functions.prf | 20 ++++++++++++-------- mkspecs/features/qt_plugin.prf | 10 ++++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index d41fe3b4d5..9a4d80e80f 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -253,11 +253,13 @@ defineTest(qtAddTargetEnv) { deps = $$replace($$2, -private$, _private) deps = $$resolve_depends(deps, "QT.", ".depends" ".private_depends" ".run_depends") !isEmpty(deps) { + ptypes = for(dep, deps) { isEmpty(3): \ deppath += $$shell_path($$eval(QT.$${dep}.libs)) else: \ deppath += $$system_path($$eval(QT.$${dep}.libs)) + ptypes += $$eval(QT.$${dep}.plugin_types) } equals(QMAKE_HOST.os, Windows) { deppath.name = PATH @@ -277,14 +279,16 @@ defineTest(qtAddTargetEnv) { deppath.CONFIG = prepend pluginpath.value = - for(qmod, QMAKEMODULES) { - qmod = $$section(qmod, /, 0, -3)/plugins - exists($$qmod) { - isEmpty(3): \ - pluginpath.value += $$shell_path($$qmod) - else: \ - pluginpath.value += $$system_path($$qmod) - } + ppaths = $$[QT_INSTALL_PLUGINS/get] + for(qplug, QT_PLUGINS): \ + contains(ptypes, QT_PLUGIN.$${qplug}.TYPE): \ + ppaths += $$eval(QT_PLUGIN.$${qplug}.PATH) + ppaths = $$unique(ppaths) + for(qplug, ppaths) { + isEmpty(3): \ + pluginpath.value += $$shell_path($$qplug) + else: \ + pluginpath.value += $$system_path($$qplug) } pluginpath.name = QT_PLUGIN_PATH diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index b012278bde..8a70ce041a 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -24,7 +24,7 @@ tool_plugin { contains(QT_CONFIG, build_all):CONFIG += build_all } -CONFIG(static, static|shared) { +CONFIG(static, static|shared)|prefix_build { isEmpty(MODULE): MODULE = $$basename(TARGET) mod_work_pfx = $$MODULE_QMAKE_OUTDIR/mkspecs/modules @@ -66,9 +66,11 @@ CONFIG(static, static|shared) { cache(QT_PLUGINS, transient) } - pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules - pritarget.files = $$MODULE_PRI - INSTALLS += pritarget + CONFIG(static, static|shared) { + pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules + pritarget.files = $$MODULE_PRI + INSTALLS += pritarget + } } target.path = $$[QT_INSTALL_PLUGINS]/$$PLUGIN_TYPE -- cgit v1.2.3 From a763500a61de7c25b73d6eb54a7d8ca60af0d79e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 21 May 2014 14:22:31 +0200 Subject: ensure that there is always an -indexdir argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit even if we are not doing a top-level build, we still need to specify an index dir. that may be the install dir or the qtbase build dir, depending on whether we are building against an installed prefix build or a non-prefix build (building against non-installed prefix builds outside a top-level build is inherently impossible). Task-number: QTBUG-35596 Change-Id: Ia37d429855480d3bfe36b7ee29e087029861bfc5 Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_docs.prf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index 8e63fa61a7..495b649b4a 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -23,9 +23,13 @@ QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR !build_online_docs: \ QDOC += -installdir $$[QT_INSTALL_DOCS] DOC_INDEXES = -for(qrep, QTREPOS): \ - exists($$qrep/doc): \ - DOC_INDEXES += -indexdir $$qrep/doc +!isEmpty(QTREPOS) { + for(qrep, QTREPOS): \ + exists($$qrep/doc): \ + DOC_INDEXES += -indexdir $$qrep/doc +} else { + DOC_INDEXES += -indexdir $$[QT_INSTALL_DOCS/get] +} qtver.name = QT_VERSION qtver.value = $$VERSION isEmpty(qtver.value): qtver.value = $$MODULE_VERSION -- cgit v1.2.3 From 939d021813974949cc21e56bf70c4340ea14fba9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 21 May 2014 14:15:24 +0200 Subject: do not auto-add install dir to index dirs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the install dir may contain indexes from previous builds. a build must never refer to previous builds. Change-Id: I67c04df8f3f82bdbebb67e280f70795ed0a76ccf Reviewed-by: Topi Reiniö Reviewed-by: Joerg Bornemann --- src/tools/qdoc/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 2c1c28ec8c..8998a27081 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -224,8 +224,7 @@ static void loadIndexFiles(Config& config) } } else { - qDebug() << "Dependant modules specified, but no index directories or " - << "install directory were set." + qDebug() << "Dependent modules specified, but no index directories were set." << "There will probably be errors for missing links."; } } @@ -618,7 +617,6 @@ int main(int argc, char **argv) } else if (opt == "-installdir") { Config::installDir = argv[i]; - indexDirs += argv[i]; i++; } else if (opt == "-obsoletelinks") { -- cgit v1.2.3 From 4c7ad3a4a1dae9b4a77cf73b079d733c9af34f87 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 23 May 2014 16:30:46 +0200 Subject: don't check for doc/ dirs' existence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the doc/ dirs in the build dir won't be created until the docs have been built, so of course checking whether they are there during the qmake phase is counterproductive. this also means that we'll get some complaints about non-existing directories (for repos that don't create any docs). there is no reasonable way to query qmake which repos are affected, and writing shell-specific code to query it at make time seems a bit overengineered. Task-number: QTBUG-38862 Change-Id: Ie0588e75bfc39718fffd46f0df6785428e396eb2 Reviewed-by: Topi Reiniö Reviewed-by: Jerome Pasion Reviewed-by: Martin Smith --- mkspecs/features/qt_docs.prf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index 495b649b4a..957b5de83a 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -25,8 +25,7 @@ QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR DOC_INDEXES = !isEmpty(QTREPOS) { for(qrep, QTREPOS): \ - exists($$qrep/doc): \ - DOC_INDEXES += -indexdir $$qrep/doc + DOC_INDEXES += -indexdir $$qrep/doc } else { DOC_INDEXES += -indexdir $$[QT_INSTALL_DOCS/get] } -- cgit v1.2.3 From 2e284a8d7ec5b8d52508b549cff2b988ade34e30 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 23 May 2014 18:05:05 +0200 Subject: pass (some) index dirs also during -prepare phase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qdoc uses the indexes as "precompiled headers" to obtain type info necessary to properly parse sources. the indexes needed are the ones the module actually depends on (publically). Change-Id: I6aad0b511d2534d584f7947c8d800300eede94ff Reviewed-by: Topi Reiniö Reviewed-by: Jerome Pasion Reviewed-by: Martin Smith --- mkspecs/features/qt_docs.prf | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index 957b5de83a..bcc16ada78 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -22,11 +22,25 @@ qtPrepareTool(QDOC, qdoc) QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR !build_online_docs: \ QDOC += -installdir $$[QT_INSTALL_DOCS] +PREP_DOC_INDEXES = DOC_INDEXES = !isEmpty(QTREPOS) { + prepare_docs { + # This is not for linking, but for providing type information. + mps = + deps = $$replace(QT, -private$, ) + deps = $$resolve_depends(deps, "QT.") + for (d, deps): \ + mps += $$dirname(QT.$${d}.libs) + mps = $$unique(mps) + for (mp, mps): \ + PREP_DOC_INDEXES += -indexdir $$mp/doc + } for(qrep, QTREPOS): \ DOC_INDEXES += -indexdir $$qrep/doc } else { + prepare_docs: \ + PREP_DOC_INDEXES += -indexdir $$[QT_INSTALL_DOCS/get] DOC_INDEXES += -indexdir $$[QT_INSTALL_DOCS/get] } qtver.name = QT_VERSION @@ -42,7 +56,7 @@ qtdocs.value = $$[QT_INSTALL_DOCS/src] qtAddToolEnv(QDOC, qtver qtmver qtvertag qtdocs) doc_command = $$QDOC $$QMAKE_DOCS prepare_docs { - prepare_docs.commands += $$doc_command -prepare -no-link-errors + prepare_docs.commands += $$doc_command -prepare $$PREP_DOC_INDEXES -no-link-errors generate_docs.commands += $$doc_command -generate $$DOC_INDEXES } else { html_docs.commands += $$doc_command $$DOC_INDEXES -- cgit v1.2.3 From 08a7828429edcb597aaaaf2e495b4d2a77cd64cc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 26 May 2014 13:43:48 +0200 Subject: install pdb files also for static libraries the condition is now consistent with that of the target itself (which means that by setting target.CONFIG=no_dll one can actually suppress installing the target itself even if it's not a dll, but anyway). Task-number: QTBUG-39253 Change-Id: Id4684a550a33b463594ab537eaa9e1cbfb61e4ff Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_nmake.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 4239ceb90f..8e609fdcae 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -270,10 +270,7 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t) targetdir += Option::dir_sep; if (project->isActiveConfig("debug_info")) { - if (t == "dlltarget" - || project->first("TEMPLATE") != "lib" - || (project->isActiveConfig("shared") - && project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1)) { + if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) { QString pdb_target = getPdbTarget(); pdb_target.remove('"'); QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target; -- cgit v1.2.3 From 12bbd15e0f9dfdf6c13980c04e284993f467893b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 26 May 2014 14:08:53 +0200 Subject: actually don't install qt dlls into lib/ any more it helps enormously to use the flag correctly. amends f0c34eb08f. Change-Id: I04a63cc59e133169d9f6677f2f88ef98fd5c524c Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_build_config.prf | 1 - mkspecs/features/qt_installs.prf | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 0bf90cc297..5fece28ca3 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -59,7 +59,6 @@ CONFIG += \ create_prl link_prl \ prepare_docs qt_docs_targets \ no_private_qt_headers_warning QTDIR_build \ - no_dll \ # Qt modules get compiled without exceptions enabled by default. # However, testcases should be still built with exceptions. exceptions_off testcase_exceptions diff --git a/mkspecs/features/qt_installs.prf b/mkspecs/features/qt_installs.prf index 7cacca9935..7d2280e75a 100644 --- a/mkspecs/features/qt_installs.prf +++ b/mkspecs/features/qt_installs.prf @@ -22,6 +22,7 @@ target.path = $$[QT_HOST_LIBS] else: \ target.path = $$[QT_INSTALL_LIBS] + target.CONFIG = no_dll INSTALLS += target } -- cgit v1.2.3 From 7a1e17a3500b182350a638ab08c8c74ee1c205c1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 2 Jun 2014 11:40:36 +0200 Subject: unbreak static qml imports again a) qmlimportscanner has no built-in -importPath, so it can't be omitted even for non-prefix builds, and b) the QMLPATHS variable is also used further down, so we can't just do away with it. amends a658fa40. Change-Id: I42a47a82fe13694fbac3c4a3962ebbe1d7e7865b Reviewed-by: Joerg Bornemann Reviewed-by: Richard Moe Gustavsen --- mkspecs/features/qt.prf | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index c3395d09ac..f8ba3c58b2 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -80,11 +80,18 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") # static builds: link qml import plugins into the app. contains(qt_module_deps, qml): \ contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { + !isEmpty(QTREPOS) { + for (qrep, QTREPOS): \ + exists($$qrep/qml): \ + QMLPATHS += $$qrep/qml + } else { + QMLPATHS += $$[QT_INSTALL_QML/get] + } + # run qmlimportscanner qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner) - for (qrep, QTREPOS): \ - exists($$qrep/qml): \ - IMPORTPATHS += -importPath $$qrep/qml + for (QMLPATH, QMLPATHS): \ + IMPORTPATHS += -importPath $$QMLPATH #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) -- cgit v1.2.3 From f9b61eca4e48f59a2d4c3b9f131b88d4e7c3b6a9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 2 Jun 2014 13:40:53 +0200 Subject: use the right env var in qmlplugindump call qml2 needs QML2_IMPORT_PATH. this didn't affect non-prefix builds (which most developers use), so it wasn't too serious. Change-Id: I435dca151348669b66f091f9a9324cd69394284e Reviewed-by: Joerg Bornemann --- mkspecs/features/qml_plugin.prf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index ad55b889ac..bfd01c6eda 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -75,10 +75,13 @@ load(qt_common) } load(resolve_target) - qml1_target: \ + qml1_target { qmlplugindump = qml1plugindump - else: \ + importpath.name = QML_IMPORT_PATH + } else { qmlplugindump = qmlplugindump + importpath.name = QML2_IMPORT_PATH + } qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump) importpath.value = for(qmod, QTREPOS) { @@ -88,7 +91,6 @@ load(qt_common) qmod = $$qmod/qml exists($$qmod): importpath.value += $$shell_path($$qmod) } - importpath.name = QML_IMPORT_PATH importpath.value = $$unique(importpath.value) qtAddToolEnv(QMLPLUGINDUMP, importpath) TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) -- cgit v1.2.3 From c54f7720d09e7d00f3309736bbeaaa6a81967ec1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 6 Jan 2014 18:00:39 +0100 Subject: fix qmaccocoaviewcontainer example - fix build on 10.6 - actually build it at all Change-Id: Ib929f8b56e55f00191f7fcfb2be25975e46a1af2 Reviewed-by: Joerg Bornemann --- examples/widgets/mac/mac.pro | 2 +- examples/widgets/mac/qmaccocoaviewcontainer/main.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/widgets/mac/mac.pro b/examples/widgets/mac/mac.pro index 1513c66ed8..7f8f79120d 100644 --- a/examples/widgets/mac/mac.pro +++ b/examples/widgets/mac/mac.pro @@ -2,6 +2,6 @@ TEMPLATE = subdirs macx { SUBDIRS = \ - qmacnativewidget \ + qmaccocoaviewcontainer \ qmacnativewidget } diff --git a/examples/widgets/mac/qmaccocoaviewcontainer/main.mm b/examples/widgets/mac/qmaccocoaviewcontainer/main.mm index e8ebc23714..e13273ce31 100644 --- a/examples/widgets/mac/qmaccocoaviewcontainer/main.mm +++ b/examples/widgets/mac/qmaccocoaviewcontainer/main.mm @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include #include +#include #include class WindowWidget : public QWidget -- cgit v1.2.3