diff options
49 files changed, 364 insertions, 277 deletions
diff --git a/examples/widgets/mac/mac.pro b/examples/widgets/mac/mac.pro index 1513c66ed8..7f8f79120d 100644 --- a/examples/widgets/mac/mac.pro +++ b/examples/widgets/mac/mac.pro @@ -2,6 +2,6 @@ TEMPLATE = subdirs macx { SUBDIRS = \ - qmacnativewidget \ + qmaccocoaviewcontainer \ qmacnativewidget } diff --git a/examples/widgets/mac/qmaccocoaviewcontainer/main.mm b/examples/widgets/mac/qmaccocoaviewcontainer/main.mm index e8ebc23714..e13273ce31 100644 --- a/examples/widgets/mac/qmaccocoaviewcontainer/main.mm +++ b/examples/widgets/mac/qmaccocoaviewcontainer/main.mm @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include <QtWidgets> #include <Cocoa/Cocoa.h> +#include <QtWidgets> #include <QMacCocoaViewContainer> class WindowWidget : public QWidget diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index ad55b889ac..bfd01c6eda 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -75,10 +75,13 @@ load(qt_common) } load(resolve_target) - qml1_target: \ + qml1_target { qmlplugindump = qml1plugindump - else: \ + importpath.name = QML_IMPORT_PATH + } else { qmlplugindump = qmlplugindump + importpath.name = QML2_IMPORT_PATH + } qtPrepareTool(QMLPLUGINDUMP, $$qmlplugindump) importpath.value = for(qmod, QTREPOS) { @@ -88,7 +91,6 @@ load(qt_common) qmod = $$qmod/qml exists($$qmod): importpath.value += $$shell_path($$qmod) } - importpath.name = QML_IMPORT_PATH importpath.value = $$unique(importpath.value) qtAddToolEnv(QMLPLUGINDUMP, importpath) TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index c3395d09ac..f8ba3c58b2 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -80,11 +80,18 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") # static builds: link qml import plugins into the app. contains(qt_module_deps, qml): \ contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { + !isEmpty(QTREPOS) { + for (qrep, QTREPOS): \ + exists($$qrep/qml): \ + QMLPATHS += $$qrep/qml + } else { + QMLPATHS += $$[QT_INSTALL_QML/get] + } + # run qmlimportscanner qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner) - for (qrep, QTREPOS): \ - exists($$qrep/qml): \ - IMPORTPATHS += -importPath $$qrep/qml + for (QMLPATH, QMLPATHS): \ + IMPORTPATHS += -importPath $$QMLPATH #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) 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 d41fe3b4d5..9a4d80e80f 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -253,11 +253,13 @@ defineTest(qtAddTargetEnv) { deps = $$replace($$2, -private$, _private) deps = $$resolve_depends(deps, "QT.", ".depends" ".private_depends" ".run_depends") !isEmpty(deps) { + ptypes = for(dep, deps) { isEmpty(3): \ deppath += $$shell_path($$eval(QT.$${dep}.libs)) else: \ deppath += $$system_path($$eval(QT.$${dep}.libs)) + ptypes += $$eval(QT.$${dep}.plugin_types) } equals(QMAKE_HOST.os, Windows) { deppath.name = PATH @@ -277,14 +279,16 @@ defineTest(qtAddTargetEnv) { deppath.CONFIG = prepend pluginpath.value = - for(qmod, QMAKEMODULES) { - qmod = $$section(qmod, /, 0, -3)/plugins - exists($$qmod) { - isEmpty(3): \ - pluginpath.value += $$shell_path($$qmod) - else: \ - pluginpath.value += $$system_path($$qmod) - } + ppaths = $$[QT_INSTALL_PLUGINS/get] + for(qplug, QT_PLUGINS): \ + contains(ptypes, QT_PLUGIN.$${qplug}.TYPE): \ + ppaths += $$eval(QT_PLUGIN.$${qplug}.PATH) + ppaths = $$unique(ppaths) + for(qplug, ppaths) { + isEmpty(3): \ + pluginpath.value += $$shell_path($$qplug) + else: \ + pluginpath.value += $$system_path($$qplug) } pluginpath.name = QT_PLUGIN_PATH diff --git a/mkspecs/features/qt_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/qnx-armle-v7-qcc/qplatformdefs.h b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h index 27e4a3aa41..2f95f0d392 100644 --- a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h +++ b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h @@ -83,7 +83,7 @@ #include <arpa/inet.h> #define QT_USE_XOPEN_LFS_EXTENSIONS -#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R) +#if !defined(__EXT_QNX__READDIR64_R) #define QT_NO_READDIR64 #endif #include "../common/posix/qplatformdefs.h" diff --git a/mkspecs/qnx-x86-qcc/qplatformdefs.h b/mkspecs/qnx-x86-qcc/qplatformdefs.h index 246f82e27f..b47aecde0d 100644 --- a/mkspecs/qnx-x86-qcc/qplatformdefs.h +++ b/mkspecs/qnx-x86-qcc/qplatformdefs.h @@ -83,7 +83,7 @@ #include <arpa/inet.h> #define QT_USE_XOPEN_LFS_EXTENSIONS -#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R) +#if !defined(__EXT_QNX__READDIR64_R) #define QT_NO_READDIR64 #endif #include "../common/posix/qplatformdefs.h" diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 4239ceb90f..8e609fdcae 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -270,10 +270,7 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t) targetdir += Option::dir_sep; if (project->isActiveConfig("debug_info")) { - if (t == "dlltarget" - || project->first("TEMPLATE") != "lib" - || (project->isActiveConfig("shared") - && project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1)) { + if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) { QString pdb_target = getPdbTarget(); pdb_target.remove('"'); QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target; diff --git a/qmake/main.cpp b/qmake/main.cpp index f5116ba752..82573a61fc 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -252,8 +252,10 @@ int runQMake(int argc, char **argv) #endif if(!dir.isNull() && dir != ".") Option::output_dir = dir; - if(QDir::isRelativePath(Option::output_dir)) + if (QDir::isRelativePath(Option::output_dir)) { + Option::output.setFileName(fi.fileName()); Option::output_dir.prepend(oldpwd + QLatin1Char('/')); + } Option::output_dir = QDir::cleanPath(Option::output_dir); } diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 6d25325890..174c1d0d8d 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -537,7 +537,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) { -#ifndef QT_BOOTSTRAPPED +#if !defined(QT_BOOTSTRAPPED) && !defined(QT_NO_SETTINGS) if (const QSettings *settings = QLibraryInfoPrivate::findConfiguration()) { QString key = QLatin1String(platformsSection); key += QLatin1Char('/'); @@ -545,7 +545,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) key += QLatin1String("Arguments"); return settings->value(key).toStringList(); } -#endif // !QT_BOOTSTRAPPED +#endif // !QT_BOOTSTRAPPED && !QT_NO_SETTINGS return QStringList(); } diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 311ebaa092..cbd3d776a7 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -113,10 +113,8 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) { jclass jQtNative = env->FindClass("org/qtproject/qt5/android/QtNative"); - if (env->ExceptionCheck()) { - env->ExceptionClear(); + if (exceptionCheck(env)) return JNI_ERR; - } jmethodID activityMethodID = env->GetStaticMethodID(jQtNative, "activity", diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp index 40c1157fb4..a5c4c36638 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.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. @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE static const char boilerplate_supported_but_time_limited[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n" + "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n" "This trial version may only be used for evaluation purposes\n" "and will shut down after 120 minutes.\n" "Registered to:\n" @@ -65,7 +65,7 @@ static const char boilerplate_supported_but_time_limited[] = static const char boilerplate_supported[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n" + "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n" "This trial version may only be used for evaluation purposes\n" "Registered to:\n" " Licensee: %2\n\n" diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp index 33e85c1505..b2043a45a1 100644 --- a/src/corelib/thread/qatomic.cpp +++ b/src/corelib/thread/qatomic.cpp @@ -58,6 +58,7 @@ \inmodule QtCore \brief The QAtomicInteger class provides platform-independent atomic operations on integers. \ingroup thread + \since 5.3 For atomic operations on pointers, see the QAtomicPointer class. diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index aac9c493c3..a018b81c38 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -9872,9 +9872,7 @@ QString QString::toHtmlEscaped() const the read-only segment of the compiled object file. For compilers not supporting the creation of compile time strings, QStringLiteral will fall back to - QLatin1String. - - The result of the QStringLiteral expression can be cast into a QString. + QString::fromUtf8(). If you have code looking like: \code diff --git a/src/gui/kernel/qplatformclipboard.cpp b/src/gui/kernel/qplatformclipboard.cpp index 5c25054260..d93268c9f2 100644 --- a/src/gui/kernel/qplatformclipboard.cpp +++ b/src/gui/kernel/qplatformclipboard.cpp @@ -123,7 +123,8 @@ bool QPlatformClipboard::ownsMode(QClipboard::Mode mode) const void QPlatformClipboard::emitChanged(QClipboard::Mode mode) { - QGuiApplication::clipboard()->emitChanged(mode); + if (!QGuiApplicationPrivate::is_app_closing) // QTBUG-39317, prevent emission when closing down. + QGuiApplication::clipboard()->emitChanged(mode); } QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 7d91d2c497..cd6468cccd 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -436,9 +436,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi samples = qBound(0, int(samples), int(maxSamples)); #endif + requestedSamples = samples; size = sz; target = texture_target; - // texture dimensions QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; @@ -472,6 +472,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi valid = checkFramebufferStatus(ctx); if (valid) { + // Query the actual number of samples. This can be greater than the requested + // value since the typically supported values are 0, 4, 8, ..., and the + // requests are mapped to the next supported value. funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); } @@ -542,7 +545,10 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment) { - int samples = format.samples(); + // Use the same sample count for all attachments. format.samples() already contains + // the actual number of samples for the color attachment and is not suitable. Use + // requestedSamples instead. + const int samples = requestedSamples; // free existing attachments if (depth_buffer_guard) { diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h index 7a653bc16d..75348d1481 100644 --- a/src/gui/opengl/qopenglframebufferobject_p.h +++ b/src/gui/opengl/qopenglframebufferobject_p.h @@ -131,6 +131,7 @@ public: GLenum target; QSize size; QOpenGLFramebufferObjectFormat format; + int requestedSamples; uint valid : 1; QOpenGLFramebufferObject::Attachment fbo_attachment; QOpenGLExtensions funcs; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index b5ccafdf9a..24da65921e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1798,71 +1798,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c } fx = v_fx.i[0]; fy = v_fy.i[0]; -#elif defined(__ARM_NEON__) - BILINEAR_ROTATE_BOUNDS_PROLOG - - const int16x8_t colorMask = vdupq_n_s16(0x00ff); - const int16x8_t invColorMask = vmvnq_s16(colorMask); - const int16x8_t v_256 = vdupq_n_s16(256); - int32x4_t v_fdx = vdupq_n_s32(fdx*4); - int32x4_t v_fdy = vdupq_n_s32(fdy*4); - - const uchar *textureData = data->texture.imageData; - const int bytesPerLine = data->texture.bytesPerLine; - - union Vect_buffer { int32x4_t vect; quint32 i[4]; }; - Vect_buffer v_fx, v_fy; - - for (int i = 0; i < 4; i++) { - v_fx.i[i] = fx; - v_fy.i[i] = fy; - fx += fdx; - fy += fdy; - } - - const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff); - - while (b < boundedEnd) { - if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2) - break; - if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1) - break; - if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2) - break; - if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1) - break; - - Vect_buffer tl, tr, bl, br; - - Vect_buffer v_fx_shifted, v_fy_shifted; - v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16); - v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16); - - for (int i = 0; i < 4; i++) { - const int x1 = v_fx_shifted.i[i]; - const int y1 = v_fy_shifted.i[i]; - const uchar *sl = textureData + bytesPerLine * y1; - const uint *s1 = (const uint *)sl; - const uint *s2 = (const uint *)(sl + bytesPerLine); - tl.i[i] = s1[x1]; - tr.i[i] = s1[x1+1]; - bl.i[i] = s2[x1]; - br.i[i] = s2[x1+1]; - } - - int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12); - int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12); - v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16)); - v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16)); - int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4); - - interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b); - b+=4; - v_fx.vect = vaddq_s32(v_fx.vect, v_fdx); - v_fy.vect = vaddq_s32(v_fy.vect, v_fdy); - } - fx = v_fx.i[0]; - fy = v_fy.i[0]; #endif } diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 32b6d902d0..360f9722c7 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1219,8 +1219,8 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS d->init(); } #else -QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent, - QHttpNetworkConnection::ConnectionType connectionType) +QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, + QHttpNetworkConnection::ConnectionType connectionType, QObject *parent) : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt , connectionType)), parent) { Q_D(QHttpNetworkConnection); diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 9d4257e217..42114ae9d6 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -110,8 +110,8 @@ public: ConnectionType connectionType = ConnectionTypeHTTP); #else explicit QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, - QObject *parent = 0, - ConnectionType connectionType = ConnectionTypeHTTP); + ConnectionType connectionType = ConnectionTypeHTTP, + QObject *parent = 0); QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0, ConnectionType connectionType = ConnectionTypeHTTP); diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl.mm b/src/network/access/qnetworkreplynsurlconnectionimpl.mm index d49324918e..f93f18357a 100644 --- a/src/network/access/qnetworkreplynsurlconnectionimpl.mm +++ b/src/network/access/qnetworkreplynsurlconnectionimpl.mm @@ -90,6 +90,7 @@ public: void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value); void setRawHeader(const QByteArray &headerName, const QByteArray &value); void setError(QNetworkReply::NetworkError errorCode, const QString &errorString); + void setAttribute(QNetworkRequest::Attribute code, const QVariant &value); }; @interface QtNSURLConnectionDelegate : NSObject @@ -140,6 +141,7 @@ QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivat void QNetworkReplyNSURLConnectionImplPrivate::setFinished() { q_func()->setFinished(true); + QMetaObject::invokeMethod(q_func(), "finished", Qt::QueuedConnection); } void QNetworkReplyNSURLConnectionImplPrivate::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) @@ -157,6 +159,11 @@ void QNetworkReplyNSURLConnectionImplPrivate::setError(QNetworkReply::NetworkErr q_func()->setError(errorCode, errorString); } +void QNetworkReplyNSURLConnectionImplPrivate::setAttribute(QNetworkRequest::Attribute code, const QVariant &value) +{ + q_func()->setAttribute(code, value); +} + void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData() { Q_D(QNetworkReplyNSURLConnectionImpl); @@ -269,6 +276,9 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData() NSString *value = [headers objectForKey:key]; replyprivate->setRawHeader(QString::fromNSString(key).toUtf8(), QString::fromNSString(value).toUtf8()); } + + int code = [httpResponse statusCode]; + replyprivate->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code); } else { if ([aResponse expectedContentLength] != NSURLResponseUnknownLength) replyprivate->setHeader(QNetworkRequest::ContentLengthHeader, [aResponse expectedContentLength]); @@ -317,8 +327,7 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData() - (void)connectionDidFinishLoading:(NSURLConnection*)connection { Q_UNUSED(connection) - replyprivate->setFinished(); - QMetaObject::invokeMethod(replyprivate->q_func(), "finished", Qt::QueuedConnection); + replyprivate->setFinished(); } - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index 26834dff57..108fcbaf60 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -370,11 +370,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN } #else - -void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply) +void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) { Q_UNUSED(requestType) Q_UNUSED(requestName) + Q_UNUSED(nameserver) reply->error = QDnsLookup::ResolverError; reply->errorString = tr("Resolver library can't be loaded: No runtime library loading support"); return; diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 8eb632ff63..1646940cb8 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -246,8 +246,11 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: d->tcp = handler->pendingTcpSockets.take(socketDescriptor); d->socketType = QAbstractSocket::TcpSocket; - if (!d->tcp || !d->fetchConnectionParameters()) + if (!d->tcp || !d->fetchConnectionParameters()) { + d->setError(QAbstractSocket::UnsupportedSocketOperationError, + d->InvalidSocketErrorString); return false; + } d->socketState = socketState; return true; @@ -475,9 +478,9 @@ void QNativeSocketEngine::close() Q_D(QNativeSocketEngine); if (d->socketDescriptor != -1) { IClosable *socket = 0; - if (d->socketType == QAbstractSocket::TcpSocket) + if (d->socketType == QAbstractSocket::TcpSocket && d->tcp) d->tcp->QueryInterface(IID_PPV_ARGS(&socket)); - else if (d->socketType == QAbstractSocket::UdpSocket) + else if (d->socketType == QAbstractSocket::UdpSocket && d->udp) d->udp->QueryInterface(IID_PPV_ARGS(&socket)); if (socket) { diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp index 80453816fc..9c2d50823a 100644 --- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp +++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp @@ -84,32 +84,22 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask); int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask); int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask); - int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size - - bool visualMatchesConfig = false; - if ( visualRedSize == configRedSize && - visualGreenSize == configGreenSize && - visualBlueSize == configBlueSize ) - { - // We need XRender to check the alpha channel size of the visual. If we don't have - // the alpha size, we don't check it against the EGL config's alpha size. - if (visualAlphaSize >= 0) - visualMatchesConfig = visualAlphaSize == configAlphaSize; - else - visualMatchesConfig = true; - } + int visualAlphaSize = chosenVisualInfo->depth == 32 ? 8 : 0; + + const bool visualMatchesConfig = visualRedSize == configRedSize + && visualGreenSize == configGreenSize + && visualBlueSize == configBlueSize + && visualAlphaSize == configAlphaSize; + // In some cases EGL tends to suggest a 24-bit visual for 8888 + // configs. In such a case we have to fall back to XGetVisualInfo. if (!visualMatchesConfig) { - if (visualAlphaSize >= 0) { - qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable", - (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize, - configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize); - } else { - qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable", - (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, - configId, configRedSize, configGreenSize, configBlueSize); - } visualId = 0; +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + qWarning("Warning: EGL suggested using X Visual ID %d (%d %d %d depth %d) for EGL config %d (%d %d %d %d), but this is incompatible", + (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, chosenVisualInfo->depth, + configId, configRedSize, configGreenSize, configBlueSize, configAlphaSize); +#endif } } else { qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID", @@ -133,8 +123,7 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay return visualId; } - // Finally, try to - // use XGetVisualInfo and only use the bit depths to match on: + // Finally, try to use XGetVisualInfo and only use the bit depths to match on: if (!visualId) { XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index d9f5cec27a..9d43c2f758 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -47,6 +47,7 @@ #include "qwindow.h" #include "qrect.h" #include "QtGui/qaccessible.h" +#include <QtCore/private/qjnihelpers_p.h> #include "qdebug.h" @@ -207,7 +208,7 @@ if (!clazz) { \ if (desc.isEmpty()) desc = iface->text(QAccessible::Description); if (QAccessibleTextInterface *textIface = iface->textInterface()) { - if (textIface->selectionCount() > 0) { + if (m_setTextSelectionMethodID && textIface->selectionCount() > 0) { int startSelection; int endSelection; textIface->selection(0, &startSelection, &endSelection); @@ -259,12 +260,15 @@ if (!clazz) { \ bool registerNatives(JNIEnv *env) { + if (QtAndroidPrivate::androidSdkVersion() < 16) + return true; // We need API level 16 or higher + jclass clazz; FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/accessibility/QtNativeAccessibility"); jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz)); if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { - __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed"); + __android_log_print(ANDROID_LOG_FATAL,"Qt A11y", "RegisterNatives failed"); return false; } @@ -277,9 +281,12 @@ if (!clazz) { \ 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"); + if (QtAndroidPrivate::androidSdkVersion() >= 18) { + GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V"); + } + return true; } } diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index d484a2faff..f711a68a71 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -423,6 +423,7 @@ namespace QtAndroid m_destroySurfaceMethodID, surfaceId); } + } // namespace QtAndroid @@ -743,15 +744,6 @@ static int registerNatives(JNIEnv *env) return JNI_TRUE; } -jint androidApiLevel(JNIEnv *env) -{ - jclass clazz; - FIND_AND_CHECK_CLASS("android/os/Build$VERSION"); - jfieldID fieldId; - GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "SDK_INT", "I"); - return env->GetStaticIntField(clazz, fieldId); -} - Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) { typedef union { @@ -774,17 +766,12 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) || !QtAndroidInput::registerNatives(env) || !QtAndroidClipboard::registerNatives(env) || !QtAndroidMenu::registerNatives(env) + || !QtAndroidAccessibility::registerNatives(env) || !QtAndroidDialogHelpers::registerNatives(env)) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } - jint apiLevel = androidApiLevel(env); - if (apiLevel >= 16 && !QtAndroidAccessibility::registerNatives(env)) { - __android_log_print(ANDROID_LOG_FATAL, "Qt A11y", "registerNatives failed"); - return -1; - } - m_javaVM = vm; return JNI_VERSION_1_4; } diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 548c6a23f0..f89439734f 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -223,7 +223,14 @@ static void cleanupCocoaApplicationDelegate() // events while the event loop is still running. const QWindowList topLevels = QGuiApplication::topLevelWindows(); for (int i = 0; i < topLevels.size(); ++i) { - QWindowSystemInterface::handleCloseEvent(topLevels.at(i)); + QWindow *topLevelWindow = topLevels.at(i); + // Widgets have alreay received a CloseEvent from the QApplication + // QCloseEvent handler. (see canQuit above). Prevent running the + // CloseEvent logic twice, call close() directly. + if (topLevelWindow->inherits("QWidgetWindow")) + topLevelWindow->close(); + else + QWindowSystemInterface::handleCloseEvent(topLevelWindow); } QWindowSystemInterface::flushWindowSystemEvents(); diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 19753ccc89..fca7fa042c 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -158,23 +158,42 @@ 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 (Qt) window which contains the point. - for (NSWindow *nsWindow in [NSApp orderedWindows]) { - if (![nsWindow isKindOfClass:[QNSWindow class]]) + NSPoint screenPoint = qt_mac_flipPoint(point); + + // Search (hit test) for the top-level window. [NSWidow windowNumberAtPoint: + // belowWindowWithWindowNumber] may return windows that are not interesting + // to Qt. The search iterates until a suitable window or no window is found. + NSInteger topWindowNumber = 0; + QWindow *window = 0; + do { + // Get the top-most window, below any previously rejected window. + topWindowNumber = [NSWindow windowNumberAtPoint:screenPoint + belowWindowWithWindowNumber:topWindowNumber]; + + // Continue the search if the window does not belong to this process. + NSWindow *nsWindow = [NSApp windowWithWindowNumber:topWindowNumber]; + if (nsWindow == 0) continue; - QNSWindow *qnsWindow = static_cast<QNSWindow *>(nsWindow); - QCocoaWindow *cocoaWindow = qnsWindow.helper.platformWindow; + + // Continue the search if the window does not belong to Qt. + if (![nsWindow conformsToProtocol:@protocol(QNSWindowProtocol)]) + continue; + + id<QNSWindowProtocol> proto = static_cast<id<QNSWindowProtocol> >(nsWindow); + QCocoaWindow *cocoaWindow = proto.helper.platformWindow; if (!cocoaWindow) continue; - QWindow *window = cocoaWindow->window(); + window = cocoaWindow->window(); + + // Continue the search if the window is not a top-level window. if (!window->isTopLevel()) continue; - if (window->geometry().contains(point)) - return window; - } - return QPlatformScreen::topLevelAt(point); + // Stop searching. The current window is the correct window. + break; + } while (topWindowNumber > 0); + + return window; } extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index f3fd06037e..4403e3c28e 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -66,6 +66,8 @@ public: void lower() Q_DECL_OVERRIDE; void propagateSizeHints() Q_DECL_OVERRIDE { } + void setOpacity(qreal) Q_DECL_OVERRIDE { } + void setMask(const QRegion &) Q_DECL_OVERRIDE { } bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 8be3846e06..d109d53168 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -54,7 +54,6 @@ QIOSInputContext *m_context; BOOL m_keyboardVisible; BOOL m_keyboardVisibleAndDocked; - BOOL m_ignoreKeyboardChanges; BOOL m_touchPressWhileKeyboardVisible; BOOL m_keyboardHiddenByGesture; QRectF m_keyboardRect; @@ -74,7 +73,6 @@ m_context = context; m_keyboardVisible = NO; m_keyboardVisibleAndDocked = NO; - m_ignoreKeyboardChanges = NO; m_touchPressWhileKeyboardVisible = NO; m_keyboardHiddenByGesture = NO; m_duration = 0; @@ -160,7 +158,7 @@ - (void) keyboardWillShow:(NSNotification *)notification { - if (m_ignoreKeyboardChanges) + if ([QUIView inUpdateKeyboardLayout]) return; // Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked. m_keyboardVisibleAndDocked = YES; @@ -175,7 +173,7 @@ - (void) keyboardWillHide:(NSNotification *)notification { - if (m_ignoreKeyboardChanges) + if ([QUIView inUpdateKeyboardLayout]) return; // Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked. m_keyboardVisibleAndDocked = NO; @@ -407,11 +405,7 @@ void QIOSInputContext::update(Qt::InputMethodQueries query) void QIOSInputContext::reset() { - // Since the call to reset will cause a 'keyboardWillHide' - // notification to be sendt, we block keyboard nofifications to avoid artifacts: - m_keyboardListener->m_ignoreKeyboardChanges = true; [m_focusView reset]; - m_keyboardListener->m_ignoreKeyboardChanges = false; } void QIOSInputContext::commit() diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index 575dedab89..122e7c604b 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -75,4 +75,5 @@ - (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query; - (void)reset; - (void)commit; ++ (bool)inUpdateKeyboardLayout; @end diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm index 03006b3f99..e65ac1cc46 100644 --- a/src/plugins/platforms/ios/quiview_textinput.mm +++ b/src/plugins/platforms/ios/quiview_textinput.mm @@ -45,9 +45,12 @@ class StaticVariables { public: QInputMethodQueryEvent inputMethodQueryEvent; + bool inUpdateKeyboardLayout; QTextCharFormat markedTextFormat; - StaticVariables() : inputMethodQueryEvent(Qt::ImQueryInput) + StaticVariables() + : inputMethodQueryEvent(Qt::ImQueryInput) + , inUpdateKeyboardLayout(false) { // There seems to be no way to query how the preedit text // should be drawn. So we need to hard-code the color. @@ -152,6 +155,47 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables); return [super resignFirstResponder]; } ++ (bool)inUpdateKeyboardLayout +{ + return staticVariables()->inUpdateKeyboardLayout; +} + +- (void)updateKeyboardLayout +{ + if (![self isFirstResponder]) + return; + + // There seems to be no API to inform that the keyboard layout needs to update. + // As a work-around, we quickly resign first responder just to reassign it again. + QScopedValueRollback<bool> rollback(staticVariables()->inUpdateKeyboardLayout); + staticVariables()->inUpdateKeyboardLayout = true; + [super resignFirstResponder]; + [self updateTextInputTraits]; + [super becomeFirstResponder]; +} + +- (void)updateUITextInputDelegate:(NSNumber *)intQuery +{ + // As documented, we should not report textWillChange/textDidChange unless the text + // was changed externally. That will cause spell checking etc to fail. But we don't + // really know if the text/selection was changed by UITextInput or Qt/app when getting + // update calls from Qt. We therefore use a less ideal approach where we always assume + // that UITextView caused the change if we're currently processing an event sendt from it. + if (m_inSendEventToFocusObject) + return; + + Qt::InputMethodQueries query = Qt::InputMethodQueries([intQuery intValue]); + if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition)) { + [self.inputDelegate selectionWillChange:id<UITextInput>(self)]; + [self.inputDelegate selectionDidChange:id<UITextInput>(self)]; + } + + if (query & Qt::ImSurroundingText) { + [self.inputDelegate textWillChange:id<UITextInput>(self)]; + [self.inputDelegate textDidChange:id<UITextInput>(self)]; + } +} + - (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query { Q_UNUSED(query); @@ -160,26 +204,13 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables); if (!focusObject) return; - if (!m_inSendEventToFocusObject) { - if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition)) - [self.inputDelegate selectionWillChange:id<UITextInput>(self)]; - if (query & Qt::ImSurroundingText) - [self.inputDelegate textWillChange:id<UITextInput>(self)]; - } - // Note that we ignore \a query, and instead update using Qt::ImQueryInput. This enables us to just // store the event without copying out the result from the event each time. Besides, we seem to be // called with Qt::ImQueryInput when only changing selection, and always if typing text. So there would // not be any performance gain by only updating \a query. staticVariables()->inputMethodQueryEvent = QInputMethodQueryEvent(Qt::ImQueryInput); QCoreApplication::sendEvent(focusObject, &staticVariables()->inputMethodQueryEvent); - - if (!m_inSendEventToFocusObject) { - if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition)) - [self.inputDelegate selectionDidChange:id<UITextInput>(self)]; - if (query & Qt::ImSurroundingText) - [self.inputDelegate textDidChange:id<UITextInput>(self)]; - } + [self updateUITextInputDelegate:[NSNumber numberWithInt:int(query)]]; } - (void)sendEventToFocusObject:(QEvent &)e @@ -189,35 +220,31 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables); return; // While sending the event, we will receive back updateInputMethodWithQuery calls. - // To not confuse iOS, we cannot not call textWillChange/textDidChange at that - // point since it will cause spell checking etc to fail. So we use a guard. + // Note that it would be more correct to post the event instead, but UITextInput expects + // callbacks to take effect immediately (it will query us for information after a callback). + QScopedValueRollback<BOOL> rollback(m_inSendEventToFocusObject); m_inSendEventToFocusObject = YES; QCoreApplication::sendEvent(focusObject, &e); - m_inSendEventToFocusObject = NO; } - (void)reset { - [self.inputDelegate textWillChange:id<UITextInput>(self)]; [self setMarkedText:@"" selectedRange:NSMakeRange(0, 0)]; [self updateInputMethodWithQuery:Qt::ImQueryInput]; - - if ([self isFirstResponder]) { - // There seem to be no way to inform that the keyboard needs to update (since - // text input traits might have changed). As a work-around, we quickly resign - // first responder status just to reassign it again: - [super resignFirstResponder]; - [self updateTextInputTraits]; - [super becomeFirstResponder]; - } - [self.inputDelegate textDidChange:id<UITextInput>(self)]; + // Guard agains recursive callbacks by posting calls to UITextInput + [self performSelectorOnMainThread:@selector(updateKeyboardLayout) withObject:nil waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(updateUITextInputDelegate:) + withObject:[NSNumber numberWithInt:int(Qt::ImQueryInput)] + waitUntilDone:NO]; } - (void)commit { - [self.inputDelegate textWillChange:id<UITextInput>(self)]; [self unmarkText]; - [self.inputDelegate textDidChange:id<UITextInput>(self)]; + // Guard agains recursive callbacks by posting calls to UITextInput + [self performSelectorOnMainThread:@selector(updateUITextInputDelegate:) + withObject:[NSNumber numberWithInt:int(Qt::ImSurroundingText)] + waitUntilDone:NO]; } - (QVariant)imValue:(Qt::InputMethodQuery)query diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 7f2ed86404..d56925d0c4 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -522,6 +522,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locale(IA2Locale *locale) QLocale l; res.country = QStringToBSTR(QLocale::countryToString(l.country())); res.language = QStringToBSTR(QLocale::languageToString(l.language())); + res.variant = QStringToBSTR(QString()); *locale = res; return S_OK; } diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 0b257cc48f..6bcfe01a18 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -893,6 +893,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms case Qt::Key_Plus: case Qt::Key_Minus: case Qt::Key_Period: + case Qt::Key_Comma: case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index a46fe437d8..74d8b7c2c8 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -337,12 +337,38 @@ void QXcbWindow::create() #endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL) { m_window = xcb_generate_id(xcb_connection()); + m_visualId = m_screen->screen()->root_visual; m_depth = m_screen->screen()->root_depth; + + uint32_t mask = 0; + uint32_t values[3]; + + if (m_format.alphaBufferSize() == 8) { + xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(m_screen->screen()); + while (depthIter.rem) { + if (depthIter.data->depth == 32) { + xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data); + if (visualIter.rem) { + m_visualId = visualIter.data->visual_id; + m_depth = 32; + uint32_t colormap = xcb_generate_id(xcb_connection()); + xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap, + xcb_parent_id, m_visualId); + mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP; + values[0] = m_screen->screen()->white_pixel; + values[1] = m_screen->screen()->black_pixel; + values[2] = colormap; + break; + } + } + xcb_depth_next(&depthIter); + } + } + m_imageFormat = imageFormatForDepth(m_depth); - m_visualId = m_screen->screen()->root_visual; Q_XCB_CALL(xcb_create_window(xcb_connection(), - XCB_COPY_FROM_PARENT, // depth -- same as root + m_depth, m_window, // window id xcb_parent_id, // parent window id rect.x(), @@ -352,8 +378,8 @@ void QXcbWindow::create() 0, // border width XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class m_visualId, // visual - 0, // value mask - 0)); // value list + mask, + values)); } connection()->addWindowEventListener(m_window, this); diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index bdc9a98f2e..c758d9f4ea 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -120,9 +120,9 @@ QPrinterInfo QPrinterPrivate::findValidPrinter(const QPrinterInfo &printer) if (printerToUse.isNull()) { printerToUse = QPrinterInfo::defaultPrinter(); if (printerToUse.isNull()) { - QList<QPrinterInfo> availablePrinters = QPrinterInfo::availablePrinters(); - if (!availablePrinters.isEmpty()) - printerToUse = availablePrinters.at(0); + QStringList availablePrinterNames = QPrinterInfo::availablePrinterNames(); + if (!availablePrinterNames.isEmpty()) + printerToUse = QPrinterInfo::printerInfo(availablePrinterNames.at(0)); } } return printerToUse; diff --git a/src/sql/doc/src/qtsql.qdoc b/src/sql/doc/src/qtsql.qdoc index 2f806b4b45..f7dc840c7b 100644 --- a/src/sql/doc/src/qtsql.qdoc +++ b/src/sql/doc/src/qtsql.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. @@ -51,10 +51,12 @@ QT += sql \endcode - \section1 Reference - These are links to the API reference materials. + \section1 Related Information + + These are links to the API reference materials and related pages. \list \li \l{Qt SQL C++ Classes}{C++ Classes} + \li \l{SQL Examples} \endlist */ diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 407253ff64..d1bf34f8e1 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.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 tools applications of the Qt Toolkit. @@ -4399,36 +4399,43 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) } QString ename = en->name().mid(en->name().lastIndexOf('/')+1); - QSet<QString> usedNames; + QMap<int, const Node*> filesToOpen; foreach (const Node* child, en->childNodes()) { if (child->subType() == Node::File) { - QString file = child->name(); - QString fileName = file.mid(file.lastIndexOf('/')+1); - QString baseName = fileName; - if ((fileName.count(QChar('.')) > 0) && - (fileName.endsWith(".cpp") || - fileName.endsWith(".h") || - fileName.endsWith(".qml"))) - baseName.truncate(baseName.lastIndexOf(QChar('.'))); - if (baseName.compare(ename, Qt::CaseInsensitive) == 0) { - if (!usedNames.contains(fileName)) { - writer.writeStartElement("fileToOpen"); - writer.writeCharacters(examplesPath + file); - writer.writeEndElement(); // fileToOpen - usedNames.insert(fileName); - } + QFileInfo fileInfo(child->name()); + QString fileName = fileInfo.fileName().toLower(); + // open .qml, .cpp and .h files with a + // basename matching the example (project) name + // QMap key indicates the priority - + // the lowest value will be the top-most file + if ((fileInfo.baseName().compare(ename, Qt::CaseInsensitive) == 0)) { + if (fileName.endsWith(".qml")) + filesToOpen.insert(0, child); + else if (fileName.endsWith(".cpp")) + filesToOpen.insert(1, child); + else if (fileName.endsWith(".h")) + filesToOpen.insert(2, child); } - else if (fileName.toLower().endsWith("main.cpp") || - fileName.toLower().endsWith("main.qml")) { - if (!usedNames.contains(fileName)) { - writer.writeStartElement("fileToOpen"); - writer.writeCharacters(examplesPath + file); - writer.writeEndElement(); // fileToOpen - usedNames.insert(fileName); - } + // main.qml takes precedence over main.cpp + else if (fileName.endsWith("main.qml")) { + filesToOpen.insert(3, child); } + else if (fileName.endsWith("main.cpp")) { + filesToOpen.insert(4, child); + } } } + + QMap<int, const Node*>::const_iterator it = filesToOpen.constEnd(); + while (it != filesToOpen.constBegin()) { + writer.writeStartElement("fileToOpen"); + if (--it == filesToOpen.constBegin()) { + writer.writeAttribute(QStringLiteral("mainFile"), QStringLiteral("true")); + } + writer.writeCharacters(examplesPath + it.value()->name()); + writer.writeEndElement(); + } + writer.writeEndElement(); // example ++i; } diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 2c1c28ec8c..8998a27081 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -224,8 +224,7 @@ static void loadIndexFiles(Config& config) } } else { - qDebug() << "Dependant modules specified, but no index directories or " - << "install directory were set." + qDebug() << "Dependent modules specified, but no index directories were set." << "There will probably be errors for missing links."; } } @@ -618,7 +617,6 @@ int main(int argc, char **argv) } else if (opt == "-installdir") { Config::installDir = argv[i]; - indexDirs += argv[i]; i++; } else if (opt == "-obsoletelinks") { diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 17ed4ca477..e5f552679c 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -779,10 +779,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) } } - // generate a move event for QWidgets without window handles. QWidgets with native - // window handles already receive a move event from - // QGuiApplicationPrivate::processGeometryChangeEvent. - if (isMove && (!q->windowHandle() || q->testAttribute(Qt::WA_DontShowOnScreen))) { + if (isMove) { QMoveEvent e(q->pos(), oldPos); QApplication::sendEvent(q, &e); } diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index fc328e7af0..35a526e77d 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -591,16 +591,24 @@ void QWidgetWindow::updateNormalGeometry() void QWidgetWindow::handleMoveEvent(QMoveEvent *event) { + // If the widget's position already matches that of the event, this is a + // result of call to QWidget::move(), which already sends an event. + const bool spontaneous = m_widget->geometry().topLeft() != event->pos(); updateGeometry(); - QGuiApplication::sendSpontaneousEvent(m_widget, event); + if (spontaneous) + QGuiApplication::sendSpontaneousEvent(m_widget, event); } void QWidgetWindow::handleResizeEvent(QResizeEvent *event) { QSize oldSize = m_widget->data->crect.size(); + // If the widget's size already matches that of the event, this is a + // result of call to QWidget::resize(), which already sends an event. + const bool spontaneous = oldSize != event->size(); updateGeometry(); - QGuiApplication::sendSpontaneousEvent(m_widget, event); + if (spontaneous) + QGuiApplication::sendSpontaneousEvent(m_widget, event); if (m_widget->d_func()->paintOnScreen()) { QRegion updateRegion(geometry()); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 54b20e36f5..96438a0bdf 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -1692,9 +1692,6 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button return; } - if (!mousePressed) - return; - const qreal mouseX = qreal(mousePos.x()); int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit); @@ -1715,7 +1712,7 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button if (newCursorPos == -1) return; - if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { + if (mousePressed && wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { selectedWordOnDoubleClick = cursor; selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); } @@ -1724,7 +1721,7 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button extendBlockwiseSelection(newCursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(newCursorPos, mouseX); - else if (!isPreediting()) + else if (mousePressed && !isPreediting()) setCursorPosition(newCursorPos, QTextCursor::KeepAnchor); if (interactionFlags & Qt::TextEditable) { diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 122ac63034..fcf6315c1f 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -2485,7 +2485,7 @@ void tst_QTcpSocket::increaseReadBufferSizeFromSlot() // like KIO's socketconnec QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout"); // set the read buffer size to less than what was written, - // and increase it from the slot, first to 384 then to 1024. + // and increase it from the slot, first to 384 then to 512. active->setReadBufferSize(256); enterLoop(10); QVERIFY2(!timeout(), "Network timeout"); diff --git a/tests/auto/other/macgui/tst_macgui.cpp b/tests/auto/other/macgui/tst_macgui.cpp index 14993145b4..4314842c50 100644 --- a/tests/auto/other/macgui/tst_macgui.cpp +++ b/tests/auto/other/macgui/tst_macgui.cpp @@ -203,6 +203,7 @@ void tst_MacGui::nonModalOrder() primary.resize(400, 400); primary.move(100, 100); primary.exec(); + QEXPECT_FAIL("", "Non-modal child windows show behind the modal dialig", Abort); QCOMPARE(primary.frontWidget, primary.secondaryWindow); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 34936fa5b8..73bec9a6b9 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -262,6 +262,7 @@ private slots: void optimizedResizeMove(); void optimizedResize_topLevel(); void resizeEvent(); + void moveEvent(); void task110173(); void testDeletionInEventHandlers(); @@ -2108,41 +2109,53 @@ void tst_QWidget::showFullScreen() class ResizeWidget : public QWidget { public: - ResizeWidget(QWidget *p = 0) : QWidget(p) + ResizeWidget(QWidget *p = 0) + : QWidget(p) + , m_spontaneousResizeEventCount(0) + , m_synthesizedResizeEventCount(0) + , m_spontaneousMoveEventCount(0) + , m_synthesizedMoveEventCount(0) { setObjectName(QLatin1String("ResizeWidget")); setWindowTitle(objectName()); - m_resizeEventCount = 0; } protected: void resizeEvent(QResizeEvent *e){ QCOMPARE(size(), e->size()); - ++m_resizeEventCount; + (e->spontaneous() ? m_spontaneousResizeEventCount : m_synthesizedResizeEventCount)++; + } + void moveEvent(QMoveEvent *e) + { + (e->spontaneous() ? m_spontaneousMoveEventCount : m_synthesizedMoveEventCount)++; } public: - int m_resizeEventCount; + int m_spontaneousResizeEventCount; + int m_synthesizedResizeEventCount; + int m_spontaneousMoveEventCount; + int m_synthesizedMoveEventCount; }; void tst_QWidget::resizeEvent() { - QSKIP("QTBUG-30744"); - { QWidget wParent; wParent.resize(200, 200); ResizeWidget wChild(&wParent); wParent.show(); QTest::qWaitForWindowExposed(&wParent); - QCOMPARE (wChild.m_resizeEventCount, 1); // initial resize event before paint + QCOMPARE (wChild.m_synthesizedResizeEventCount, 1); // initial resize event before paint + QCOMPARE (wChild.m_spontaneousResizeEventCount, 0); wParent.hide(); QSize safeSize(640,480); if (wChild.size() == safeSize) safeSize.setWidth(639); wChild.resize(safeSize); - QCOMPARE (wChild.m_resizeEventCount, 1); + QCOMPARE (wChild.m_synthesizedResizeEventCount, 1); + QCOMPARE (wChild.m_spontaneousResizeEventCount, 0); wParent.show(); - QCOMPARE (wChild.m_resizeEventCount, 2); + QCOMPARE (wChild.m_synthesizedResizeEventCount, 2); + QCOMPARE (wChild.m_spontaneousResizeEventCount, 0); } { @@ -2150,19 +2163,39 @@ void tst_QWidget::resizeEvent() wTopLevel.resize(200, 200); wTopLevel.show(); QTest::qWaitForWindowExposed(&wTopLevel); - QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels + const int synthesizedResizeEventCountAfterShow = wTopLevel.m_synthesizedResizeEventCount; + QCOMPARE (synthesizedResizeEventCountAfterShow, 1); // initial resize event before paint for toplevels + QCOMPARE (wTopLevel.m_spontaneousResizeEventCount, 0); wTopLevel.hide(); QSize safeSize(640,480); if (wTopLevel.size() == safeSize) safeSize.setWidth(639); wTopLevel.resize(safeSize); - QCOMPARE (wTopLevel.m_resizeEventCount, 1); + QCOMPARE (wTopLevel.m_synthesizedResizeEventCount, synthesizedResizeEventCountAfterShow); + QCOMPARE (wTopLevel.m_spontaneousResizeEventCount, 0); wTopLevel.show(); QTest::qWaitForWindowExposed(&wTopLevel); - QCOMPARE (wTopLevel.m_resizeEventCount, 2); +#ifdef Q_OS_OSX + QEXPECT_FAIL("", "QTBUG-30744", Abort); +#endif + QCOMPARE (wTopLevel.m_synthesizedResizeEventCount, synthesizedResizeEventCountAfterShow + 1); + QCOMPARE (wTopLevel.m_spontaneousResizeEventCount, 0); } } +void tst_QWidget::moveEvent() +{ + ResizeWidget wTopLevel; + wTopLevel.resize(200, 200); + centerOnScreen(&wTopLevel); + wTopLevel.show(); + QTest::qWaitForWindowExposed(&wTopLevel); + const int synthesizedMoveEventCountAfterShow = wTopLevel.m_synthesizedMoveEventCount; + wTopLevel.move(wTopLevel.pos() + QPoint(20, 20)); + QTRY_COMPARE (wTopLevel.m_synthesizedMoveEventCount, synthesizedMoveEventCountAfterShow + 1); + QCOMPARE (wTopLevel.m_spontaneousMoveEventCount, 0); +} + void tst_QWidget::showMinimized() { QWidget plain; |