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/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 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/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} 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/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) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index f161a71ef9..bfd01c6eda 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -75,18 +75,22 @@ 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, 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 importpath.value = $$unique(importpath.value) qtAddToolEnv(QMLPLUGINDUMP, importpath) TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 0830ed2c9b..90640af64a 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -80,13 +80,16 @@ 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, _SYS) - for (MODULE, QT_MODULES) { - PATH = $$eval(QT.$${MODULE}.qml) - !isEmpty(PATH):exists($$PATH): QMLPATHS += $$PATH - } - QMLPATHS = $$unique(QMLPATHS) for (QMLPATH, QMLPATHS): \ IMPORTPATHS += -importPath $$QMLPATH 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_docs.prf b/mkspecs/features/qt_docs.prf index 8e63fa61a7..bcc16ada78 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -22,10 +22,27 @@ qtPrepareTool(QDOC, qdoc) QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR !build_online_docs: \ QDOC += -installdir $$[QT_INSTALL_DOCS] +PREP_DOC_INDEXES = DOC_INDEXES = -for(qrep, QTREPOS): \ - exists($$qrep/doc): \ +!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 qtver.value = $$VERSION isEmpty(qtver.value): qtver.value = $$MODULE_VERSION @@ -39,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 diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 64b9fee361..9a4d80e80f 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, ) } @@ -249,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 @@ -273,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_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 } 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 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.") diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 444b8b873e..46fe1e57e4 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 @@ -59,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: \ @@ -77,16 +80,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 +99,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 +147,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/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 = 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/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 90bfeccf9f..0ac840d9c9 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -809,8 +809,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" 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 52511b2008..6189a01ef3 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") @@ -260,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; 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; 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/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 7e7312cde8..1561cead86 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -119,6 +119,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; @@ -673,7 +674,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); @@ -683,6 +684,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); @@ -1007,6 +1012,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)); @@ -1032,9 +1042,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)) @@ -1071,12 +1082,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 43b04d17f0..13d6359d36 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; @@ -889,6 +890,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/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 + diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index f16144771f..9139e61700 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; } 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/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), diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 726117b515..4aa25e5450 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1841,8 +1841,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 @@ -1992,6 +1993,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 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/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. + Starts the program set by setProgram() with 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. - - \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. - The \a program string can also contain quotes, to ensure that arguments - containing spaces are correctly supplied to the new process. + 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() */ -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(); diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 63a0266948..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 @@ -1084,10 +1087,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 172ea3fc3d..aa3b710f52 100644 --- a/src/corelib/io/qstandardpaths_winrt.cpp +++ b/src/corelib/io/qstandardpaths_winrt.cpp @@ -90,10 +90,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/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 3e303e529c..fd70bcddce 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 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/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c0773882f3..a8e9f4a7e9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -515,7 +515,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 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/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/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/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 5e90a03d7f..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; } @@ -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 <> @@ -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)); 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/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(); 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 */ 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. 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; - - // 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__); + 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()); - } + copyImageDataCreateAlpha(data.data(), &image); + return image; +} + +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(); + 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)); 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 } /*! diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index af0abb5ea7..231e475111 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(); 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); } diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 9a0ecee3f6..b64956c65c 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2447,7 +2447,9 @@ bool QOpenGLTexture::isFixedSamplePositions() const void QOpenGLTexture::allocateStorage() { Q_D(QOpenGLTexture); - d->allocateStorage(); + if (d->create()) { + d->allocateStorage(); + } } /*! @@ -2805,33 +2807,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: @@ -3162,7 +3180,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; 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; 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; } } 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/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/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..e02cd98e08 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()); @@ -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_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 5e2fc1233d..472e0cb98c 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) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index db1d3dc96b..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; @@ -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/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 04c0fb0487..8fd9114b2e 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(); @@ -1810,7 +1812,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: 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; 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; } } 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/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 } } 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 34db729289..f0c4a1de2a 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) @@ -111,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); @@ -118,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); @@ -143,7 +168,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/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 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 diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index f03f551d8a..e67a039ff4 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); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 6d2c2a401e..b309df6242 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 d322079cb2..a2f9f8c984 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/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index de6c6585e9..dc0b8fcc18 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); }; @@ -180,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 e0ce9f9648..e7f8992c6d 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 @@ -622,7 +632,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 +641,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; @@ -717,10 +731,9 @@ 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(); // Add a new, empty (null), NSModalSession to the stack. // It will become active the next time QEventDispatcher::processEvents is called. @@ -733,24 +746,6 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) cocoaModalSessionStack.push(info); updateChildrenWorksWhenModal(); currentModalSessionCached = 0; - if (currentExecIsNSAppRun) { - QEvent *e = new QEvent(QEvent::User); - qApp->postEvent(q, e, Qt::HighEventPriority); - } 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) @@ -772,10 +767,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; @@ -878,10 +870,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() return; } - if (cleanupModalSessionsNeeded) - cleanupModalSessions(); - - if (interrupt) { + if (processEventsCalled > 0 && interrupt) { if (currentExecIsNSAppRun) { // The event dispatcher has been interrupted. But since // [NSApplication run] is running the event loop, we @@ -903,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) @@ -948,23 +952,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(); + 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(); - } + // 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() 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 e7a973e45b..8723b20615 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(); @@ -517,16 +520,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/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 diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 651fedb26e..c8ca494b33 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -182,13 +182,22 @@ static bool isMouseEvent(NSEvent *ev) - (void)detachFromPlatformWindow { + _platformWindow = 0; [self.window.delegate release]; self.window.delegate = nil; } - (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 @@ -261,8 +270,6 @@ static bool isMouseEvent(NSEvent *ev) { [self close]; - QCocoaIntegration::instance()->setWindow(self, 0); - if (self.helper.grabbingMouse) { self.helper.releaseOnMouseUp = YES; } else { @@ -329,7 +336,6 @@ static bool isMouseEvent(NSEvent *ev) { [self.helper detachFromPlatformWindow]; [self close]; - QCocoaIntegration::instance()->setWindow(self, 0); [self release]; } @@ -1001,9 +1007,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; } @@ -1404,7 +1415,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]; } @@ -1413,8 +1430,6 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() applyContentBorderThickness(createdWindow); - QCocoaIntegration::instance()->setWindow(createdWindow, this); - return createdWindow; } 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 a838950c9e..4c39560cbe 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -211,118 +211,16 @@ private: bool m_roundCoordinates; }; -static ComPtr painterPathToID2D1PathGeometry(const QPainterPath &path, bool alias) -{ - Direct2DPathGeometryWriter writer; - if (!writer.begin()) - return NULL; +struct D2DVectorPathCache { + ComPtr aliased; + ComPtr antiAliased; - 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; - } + static void cleanup_func(QPaintEngineEx *engine, void *data) { + Q_UNUSED(engine); + D2DVectorPathCache *e = static_cast(data); + delete e; } - - writer.close(); - return writer.geometry(); -} - -static ComPtr vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias) -{ - 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(); - return writer.geometry(); -} +}; class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate { @@ -426,7 +324,7 @@ public: dc()->PushAxisAlignedClip(rect, antialiasMode()); pushedClips.push(AxisAlignedClip); } else { - ComPtr geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__); return; @@ -571,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; @@ -835,6 +734,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()); @@ -871,7 +868,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev) QPainterPath p; p.addRegion(systemClip()); - ComPtr geometry = painterPathToID2D1PathGeometry(p, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = d->vectorPathToID2D1PathGeometry(qtVectorPathForPath(p)); if (!geometry) return false; @@ -938,7 +935,7 @@ void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) { Q_D(QWindowsDirect2DPaintEngine); - ComPtr geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + ComPtr geometry = d->vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -978,7 +975,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 = d->vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -1016,7 +1013,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 = d->vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); return; @@ -1163,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); @@ -1184,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); @@ -1216,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); @@ -1468,29 +1492,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); } } 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; } 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); diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp index 3109388fb2..7ae042cb50 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[] = { @@ -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"); } } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index f081bbd307..e4d60d6ec8 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/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; 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/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/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/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 70bb9469db..f4e1fbe533 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,13 @@ void QWinRTFontDatabase::releaseHandle(void *handle) QBasicFontDatabase::releaseHandle(handle); } -#endif // !Q_OS_WINPHONE +#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 b318a95502..eabcc83afd 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,9 +61,9 @@ class QWinRTFontDatabase : public QBasicFontDatabase { public: QString fontDir() const; -#ifndef Q_OS_WINPHONE - ~QWinRTFontDatabase(); QFont defaultFont() const Q_DECL_OVERRIDE; +#ifdef QT_WINRT_USE_DWRITE + ~QWinRTFontDatabase(); void populateFontDatabase() Q_DECL_OVERRIDE; void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) 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/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/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp index 2c8d33da84..d4034ec571 100644 --- a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp +++ b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp @@ -50,25 +50,27 @@ 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 +#else + Q_UNUSED(type) +#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/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index e2ff7197aa..f948cf9924 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(); @@ -898,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; } @@ -914,9 +978,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 +1045,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 +1062,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/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/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; }; 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 } diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index c18764a4bb..df929c4b61 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -516,6 +516,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 1af9f1fdd1..12143a7e4b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -465,6 +465,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 0315d0762f..36a4b5c5db 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -128,6 +128,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 e4ffda21ea..4b9a99486f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -202,6 +202,7 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_eglSurface(0) #endif , m_lastWindowStateEvent(-1) + , m_syncState(NoSyncNeeded) { m_screen = static_cast(window->screen()->handle()); @@ -369,7 +370,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); @@ -1728,6 +1734,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(); @@ -1801,6 +1809,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; } @@ -2077,12 +2088,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; } } @@ -2305,4 +2321,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 268a2aeaa5..72b5c7bcc9 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -146,7 +146,6 @@ 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) @@ -158,6 +157,11 @@ public: QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); + bool needsSync() const; + +public Q_SLOTS: + void updateSyncRequestCounter(); + private: void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); NetWmStates netWmStates(); @@ -224,8 +228,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 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/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()) { diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp index 8fbf20529c..1adfcfa630 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. @@ -978,6 +978,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); @@ -1120,14 +1138,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; } @@ -1343,12 +1359,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; @@ -1377,7 +1393,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/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); diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 3f3c11cc90..21ca2c4820 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -85,7 +85,6 @@ static QStringList dependModules; static QStringList indexDirs; static QString currentDir; static QString prevCurrentDir; -static QString documentationPath; /*! Print the help message to \c stdout. @@ -156,11 +155,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++) { @@ -231,8 +225,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."; } } @@ -637,7 +630,6 @@ int main(int argc, char **argv) } else if (opt == "-installdir") { Config::installDir = argv[i]; - indexDirs += argv[i]; i++; } else if (opt == "-obsoletelinks") { 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/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/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index edb9e9036c..94fcee4553 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -152,6 +152,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; @@ -392,6 +406,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 @@ -1153,6 +1169,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); @@ -1217,6 +1235,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; 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; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 7c5def5bd6..3f915264c8 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -357,11 +357,11 @@ void QWidgetPrivate::scrollChildren(int dx, int dy) } } -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); } void QWidgetPrivate::updateWidgetTransform(QEvent *event) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index e7ffb75891..14831efca8 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/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(); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 4a9852108c..94498f48c9 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 1d75894cd6..e3699da7ef 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -1968,6 +1968,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; } 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() 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())); } } diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index 9cae582143..7e04fa5957 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() 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 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" 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) diff --git a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp index 2c45b7d2ec..a4e1490b01 100644 --- a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp @@ -951,6 +951,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 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 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() diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index f686b5854c..c89b05616d 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 @@ -4213,14 +4225,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)); @@ -4228,9 +4244,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())); @@ -4238,7 +4252,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())); @@ -4246,9 +4260,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()); @@ -4256,9 +4268,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 /* 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 { 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 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: + + + + + +