From 5e76cb16924a42cb020786f45cc3494dd5836c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 5 Apr 2017 12:39:15 +0200 Subject: Fix menu position when highdpi scaling Certain display and scale factor configurations would cause menus to pop up in incorrect locations or not be shown at all. This was due to QDesktopWidget::screenNumber() having a toNativePixels(QRect, QWindow) call which requires that QWindow::screen() returns the correct screen. Break the circular dependency by converting coordinates the other way for the intersection test: transform screen geometry to device independent coordinates. Task-number: QTBUG-58329 Change-Id: I5621de89a9a2b8df44bdae528baf011fc111eba3 Reviewed-by: Paolo Angelelli Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/widgets/kernel/qdesktopwidget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index eee818b685..1e6fbfd239 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -269,12 +269,13 @@ int QDesktopWidget::screenNumber(const QWidget *w) const QRect frame = w->frameGeometry(); if (!w->isWindow()) frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); - const QRect nativeFrame = QHighDpi::toNativePixels(frame, winHandle); QScreen *widgetScreen = Q_NULLPTR; int largestArea = 0; foreach (QScreen *screen, screens) { - const QRect intersected = screen->handle()->geometry().intersected(nativeFrame); + const QRect deviceIndependentScreenGeometry = + QHighDpi::fromNativePixels(screen->handle()->geometry(), screen); + const QRect intersected = deviceIndependentScreenGeometry.intersected(frame); int area = intersected.width() * intersected.height(); if (largestArea < area) { widgetScreen = screen; -- cgit v1.2.3 From 872bff5b24ded4a5dfecad96df907f32830a980a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 31 Oct 2016 16:07:53 -0700 Subject: Enable a given SIMD feature if the compiler has enabled it Change-Id: I09100678ff4443e6be06fffd1482c08125adc0a4 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/tools/qsimd_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index f6164e2297..d5d887598e 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -169,7 +169,7 @@ || (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409)) \ && !defined(QT_BOOTSTRAPPED) # define QT_COMPILER_SUPPORTS_SIMD_ALWAYS -# define QT_COMPILER_SUPPORTS_HERE(x) QT_COMPILER_SUPPORTS(x) +# define QT_COMPILER_SUPPORTS_HERE(x) (__ ## x ## __) || QT_COMPILER_SUPPORTS(x) # if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) /* GCC requires attributes for a function */ # define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x))) -- cgit v1.2.3 From 4a6cb89f2944b5d8ee3e50fd3a2085eba9189680 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Wed, 5 Apr 2017 18:35:52 +0200 Subject: Fix reusing FTP connection after abort The QNetworkAccessCache was keeping the connection alive and it was trying to reuse it for subsequent calls to download files from the same server. After closing the connection, it is not usable anymore and a new one should be created. Task-number: QTBUG-40368 Change-Id: I1a0d08956a94eb36f39d14112cdcab6c1e2add82 Reviewed-by: Edward Welbourne --- src/network/access/qnetworkaccessftpbackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index d242bdba82..6d1ee645fe 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -114,7 +114,7 @@ QNetworkAccessFtpBackend::~QNetworkAccessFtpBackend() //if backend destroyed while in use, then abort (this is the code path from QNetworkReply::abort) if (ftp && state != Disconnecting) ftp->abort(); - disconnectFromFtp(); + disconnectFromFtp(RemoveCachedConnection); } void QNetworkAccessFtpBackend::open() -- cgit v1.2.3 From 944bf6867f8360e7ec79f542f65b4ea556ecc4e5 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Sun, 5 Mar 2017 17:28:56 +0100 Subject: Add more information about how to get a QString from qgetenv Change-Id: Ic712654c8d4735a59bf02cf6a7e1c689ca9a886c Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 54df8b1f61..6b3cb502e5 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3220,12 +3220,16 @@ static QBasicMutex environmentMutex; Returns the value of the environment variable with name \a varName. To get the variable string, use QByteArray::constData(). + To convert the data to a QString use QString::fromLocal8Bit(). \note qgetenv() was introduced because getenv() from the standard C library was deprecated in VC2005 (and later versions). qgetenv() uses the new replacement function in VC, and calls the standard C library's implementation on all other platforms. + \warning Don't use qgetenv on Windows if the content may contain + non-US-ASCII characters, like file paths. + \sa qputenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty() */ QByteArray qgetenv(const char *varName) -- cgit v1.2.3 From 07bd5a90a3dccaa31940e3b1a78069f55e25405a Mon Sep 17 00:00:00 2001 From: Filipe Azevedo Date: Tue, 13 Dec 2016 16:02:23 +0100 Subject: Fix hidpi support for opengl window grabbing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now set the QImage devicePixelRatio so the content is correct on all screens. Task-number: QTBUG-53795 Change-Id: Ic92eee98f691ebb1e0212498c1ae13ede74bca93 Reviewed-by: Laszlo Agocs Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qopenglwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index e1bd3d11b2..5170c7ab63 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -528,7 +528,9 @@ QImage QOpenGLWindow::grabFramebuffer() return QImage(); makeCurrent(); - return qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false); + QImage img = qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false); + img.setDevicePixelRatio(devicePixelRatio()); + return img; } /*! -- cgit v1.2.3 From 75cdf654bcc192ba73a8834e507583a59140e7e4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 7 Apr 2017 13:12:05 -0700 Subject: QMap: fix UB (invalid cast) in QMapData::end() The end() pointer, like in all other containers, is a sentinel value that must never be dereferenced. But unlike array-based containers, end() in QMap is not "last element plus one", but points to a base class of Node, not a full Node. Therefore, the casting from QMapNodeBase to QMapNode must not be a static_cast, reinterpret_cast is required. libstdc++-v3's red-black tree had the exact same problem: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60734 Change-Id: I43f05fedf0b44314a2dafffd14b33697861ae589 Reviewed-by: Marc Mutz --- src/corelib/tools/qmap.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 3f4f034b4e..da77ba4458 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -209,8 +209,10 @@ struct QMapData : public QMapDataBase Node *root() const { return static_cast(header.left); } - const Node *end() const { return static_cast(&header); } - Node *end() { return static_cast(&header); } + // using reinterpret_cast because QMapDataBase::header is not + // actually a QMapNode. + const Node *end() const { return reinterpret_cast(&header); } + Node *end() { return reinterpret_cast(&header); } const Node *begin() const { if (root()) return static_cast(mostLeftNode); return end(); } Node *begin() { if (root()) return static_cast(mostLeftNode); return end(); } -- cgit v1.2.3 From 9d1203bf02abec8b5ab73c4c8a81eb4627336ad8 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 9 Apr 2017 09:19:41 +0200 Subject: QVariant: fix docs regarding QUuid - toUuid(): QUuid is a built-in type, so use type(), not userType() - canConvert()/toUuid(): QUuid converts to and from QString Change-Id: I5262ff7ab093040cb943b6ab9cfffe95491d2b9b Reviewed-by: Thiago Macieira --- src/corelib/kernel/qvariant.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 7c9df5b46f..8ad61be8ee 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2526,8 +2526,9 @@ QRegularExpression QVariant::toRegularExpression() const /*! \since 5.0 - Returns the variant as a QUuid if the variant has userType() \l - QUuid; otherwise returns a default constructed QUuid. + Returns the variant as a QUuid if the variant has type() + \l QMetaType::QUuid or \l QMetaType::QString; + otherwise returns a default-constructed QUuid. \sa canConvert(), convert() */ @@ -2995,7 +2996,7 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject) \l QMetaType::QDate, \l QMetaType::QDateTime, \l QMetaType::Double, \l QMetaType::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence, \l QMetaType::LongLong, \l QMetaType::QStringList, \l QMetaType::QTime, - \l QMetaType::UInt, \l QMetaType::ULongLong + \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid \row \li \l QMetaType::QStringList \li \l QMetaType::QVariantList, \l QMetaType::QString (if the list contains exactly one item) \row \li \l QMetaType::QTime \li \l QMetaType::QString @@ -3005,6 +3006,7 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject) \row \li \l QMetaType::ULongLong \li \l QMetaType::Bool, \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt + \row \li \l QMetaType::QUuid \li \l QMetaType::QString \endtable A QVariant containing a pointer to a type derived from QObject will also return true for this -- cgit v1.2.3 From 2099709a721e2bc72350a02757099df6629475ca Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 10 Apr 2017 09:52:16 +0300 Subject: Fix build: Remove unused variable Change-Id: Ib5e7782e23eb1ff976caedd167d3df8b857d9883 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidplatformopenglcontext.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp index 6f979f614c..bef6bb9d42 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp @@ -67,10 +67,7 @@ void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface) bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface) { - bool ret = QEGLPlatformContext::makeCurrent(surface); - QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context()); - - return ret; + return QEGLPlatformContext::makeCurrent(surface); } EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) -- cgit v1.2.3 From 6c4cbd4122edf8b78f34778400d485b11da98404 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 10 Apr 2017 14:19:12 +0300 Subject: Android: Fix crash at exit We need to remove and release the surface imediately, otherwise setSurface might be called after the object is deleted. Task-number: QTBUG-59818 Change-Id: I3a09e3de1ceecc22d8d7a48e2fc1cfe40cf09f0a Reviewed-by: Laszlo Agocs Reviewed-by: Mathias Hasselmann Reviewed-by: Christian Stromme --- src/plugins/platforms/android/androidjnimain.cpp | 27 +++++++++++----------- .../platforms/android/qandroidplatformscreen.cpp | 3 +++ 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 17c197ea38..bde7457c0b 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -402,11 +402,16 @@ namespace QtAndroid if (surfaceId == -1) return; - QJNIEnvironmentPrivate env; - if (!env) - return; + { + QMutexLocker lock(&m_surfacesMutex); + const auto &it = m_surfaces.find(surfaceId); + if (it != m_surfaces.end()) + m_surfaces.erase(it); + } - env->CallStaticVoidMethod(m_applicationClass, + QJNIEnvironmentPrivate env; + if (env) + env->CallStaticVoidMethod(m_applicationClass, m_destroySurfaceMethodID, surfaceId); } @@ -584,18 +589,12 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, { QMutexLocker lock(&m_surfacesMutex); const auto &it = m_surfaces.find(id); - if (it == m_surfaces.end()) { - qWarning()<<"Can't find surface" << id; - return; - } - auto surfaceClient = it.value(); - if (!surfaceClient) // This should never happen... + if (it == m_surfaces.end()) return; - surfaceClient->surfaceChanged(env, jSurface, w, h); - - if (!jSurface) - m_surfaces.erase(it); + auto surfaceClient = it.value(); + if (surfaceClient) + surfaceClient->surfaceChanged(env, jSurface, w, h); } static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 155d6bfb8d..3b59b293a5 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -311,10 +311,13 @@ void QAndroidPlatformScreen::doRedraw() } } if (!hasVisibleRasterWindows) { + lockSurface(); if (m_id != -1) { QtAndroid::destroySurface(m_id); + releaseSurface(); m_id = -1; } + unlockSurface(); return; } QMutexLocker lock(&m_surfaceMutex); -- cgit v1.2.3 From 187427c0aec83deb08c9bd6466b5803089bd2c93 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 10 Apr 2017 15:06:08 +0300 Subject: Use latest stable version of the android:gradle plugin Change-Id: I15418015c6a206dd1a8e4b52894ec83ddaeb9fc2 Reviewed-by: Jake Petroules --- src/android/templates/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index dbe841255d..3a3e0cd165 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -4,7 +4,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:2.2.0' + classpath 'com.android.tools.build:gradle:2.2.3' } } -- cgit v1.2.3 From eda7f6ea7863b80985f62b28fe99c1176bc54c77 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 6 Apr 2017 11:14:26 +0300 Subject: Don't hide critical info The developer should see what's wrong even on release builds. That code hides any mistakes we do in JNI which are pretty critical for developers because they can't see what's wrong with their code. e.g. QtAndroid::activity().callMethod("wrongMethodName") *silently* fails, which is so wrong! Change-Id: I8b6a24946dfef716fcd86ab9bba82666974e3991 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qjni.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 41d55c8fde..60154328c2 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -64,9 +64,7 @@ static QString qt_convertJString(jstring string) static inline bool exceptionCheckAndClear(JNIEnv *env) { if (Q_UNLIKELY(env->ExceptionCheck())) { -#ifdef QT_DEBUG env->ExceptionDescribe(); -#endif // QT_DEBUG env->ExceptionClear(); return true; } -- cgit v1.2.3 From 850c5dbcd3e56589a2825a7a156a14a0ccdd220d Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 19 Jan 2017 12:25:57 +0100 Subject: Doc: minor language issues in Qt Sql doc Change-Id: If9ad86644c097d78895e392acdf017f176d8f95d Reviewed-by: Edward Welbourne --- src/sql/doc/src/sql-driver.qdoc | 54 ++++++++++++++++++------------------ src/sql/doc/src/sql-programming.qdoc | 13 ++++----- 2 files changed, 33 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc index 364d733e92..4f3f2ce007 100644 --- a/src/sql/doc/src/sql-driver.qdoc +++ b/src/sql/doc/src/sql-driver.qdoc @@ -62,7 +62,7 @@ \endtable SQLite is the in-process database system with the best test coverage - and support on all platforms. Oracle via OCI, and PostreSQL and MySQL + and support on all platforms. Oracle via OCI, PostgreSQL, and MySQL through either ODBC or a native driver are well-tested on Windows and Linux. The completeness of the support for other systems depends on the availability and quality of client libraries. @@ -92,7 +92,7 @@ on Windows), then pass the following parameter to configure: \c -I/usr/local/mysql (or \c{-I C:\mysql\include} for Windows). - On Windows the \c -I parameter doesn't accept spaces in + On Windows, the \c -I parameter doesn't accept spaces in filenames, so use the 8.3 name instead; for example, use \c{C:\progra~1\mysql} instead of \c{C:\Program Files\mysql}. @@ -110,7 +110,7 @@ \section3 QMYSQL Stored Procedure Support MySQL 5 introduces stored procedure support at the SQL level, but no - API to control IN, OUT and INOUT parameters. Therefore, parameters + API to control IN, OUT, and INOUT parameters. Therefore, parameters have to be set and read using SQL commands instead of QSqlQuery::bindValue(). Example stored procedure: @@ -141,8 +141,8 @@ \section3 How to Build the QMYSQL Plugin on Unix and \macos - You need the MySQL header files and as well as the shared library - \c{libmysqlclient.so}. Depending on your Linux distribution you may + You need the MySQL header files, as well as the shared library + \c{libmysqlclient.so}. Depending on your Linux distribution, you may need to install a package which is usually called "mysql-devel". Tell \l qmake where to find the MySQL header files and shared @@ -168,10 +168,10 @@ If you are not using a Microsoft compiler, replace \c nmake with \c make in the line above. - \note Including \c{"-o Makefile"} as an argument to \l qmake to - tell it where to build the makefile can cause the plugin to be - built in release mode only. If you are expecting a debug version - to be built as well, don't use the \c{"-o Makefile"} option. + \note Including \c{"-o Makefile"} as an argument to \l qmake, to + tell it where to build the makefile, can cause the plugin to be + built in release mode only. If you intend to build a debug version + as well, don't use the \c{"-o Makefile"} option. \target QOCI \section2 QOCI for the Oracle Call Interface (OCI) @@ -184,7 +184,7 @@ It's possible to connect to a Oracle database without a tnsnames.ora file. This requires that the database SID is passed to the driver as the database - name and that a hostname is given. + name, and that a hostname is given. \section3 OCI User Authentication @@ -230,13 +230,13 @@ \snippet code/doc_src_sql-driver.qdoc 7 \b{Note:} If you are using the Oracle Instant Client package, - you will need to set LD_LIBRARY_PATH when building the OCI SQL plugin + you will need to set LD_LIBRARY_PATH when building the OCI SQL plugin, and when running an application that uses the OCI SQL plugin. You can - avoid this requirement by setting and RPATH and listing all of the + avoid this requirement by setting RPATH, and listing all of the libraries to link to. Here is an example: \snippet code/doc_src_sql-driver.qdoc 32 - If you wish to build the OCI plugin manually with this method the procedure looks like this: + If you wish to build the OCI plugin manually with this method, the procedure looks like this: \snippet code/doc_src_sql-driver.qdoc 33 \section3 How to Build the OCI Plugin on Windows @@ -254,7 +254,7 @@ If you are not using a Microsoft compiler, replace \c nmake with \c make in the line above. - When you run your application you will also need to add the \c oci.dll + When you run your application, you will also need to add the \c oci.dll path to your \c PATH environment variable: \snippet code/doc_src_sql-driver.qdoc 9 @@ -271,25 +271,25 @@ driver manager that is installed on your system. The QODBC plugin then allows you to use these data sources in your Qt applications. - \b{Note:} You should use native drivers in preference to the ODBC - driver where they are available. ODBC support can be used as a fallback - for compliant databases if no native drivers are available. + \b{Note:} You should use the native driver, if it is available, instead + of the ODBC driver. ODBC support can be used as a fallback for compliant + databases if no native driver is available. - On Windows an ODBC driver manager should be installed by default. - For Unix systems there are some implementations which must be + On Windows, an ODBC driver manager should be installed by default. + For Unix systems, there are some implementations which must be installed first. Note that every client that uses your application is required to have an ODBC driver manager installed, otherwise the QODBC plugin will not work. - Be aware that when connecting to an ODBC datasource you must pass in - the name of the ODBC datasource to the QSqlDatabase::setDatabaseName() - function rather than the actual database name. + When connecting to an ODBC datasource, you should pass the name + of the ODBC datasource to the QSqlDatabase::setDatabaseName() + function, rather than the actual database name. The QODBC Plugin needs an ODBC compliant driver manager version 2.0 or - later to work. Some ODBC drivers claim to be version 2.0 compliant, + later. Some ODBC drivers claim to be version-2.0-compliant, but do not offer all the necessary functionality. The QODBC plugin therefore checks whether the data source can be used after a - connection has been established and refuses to work if the check + connection has been established, and refuses to work if the check fails. If you don't like this behavior, you can remove the \c{#define ODBC_CHECK_DRIVER} line from the file \c{qsql_odbc.cpp}. Do this at your own risk! @@ -332,7 +332,7 @@ driver and the DBMS must also support Unicode. Some driver managers and drivers don't support UNICODE. To use the - QODBC plugin with such drivers it has to be compiled with the + QODBC plugin with such drivers, it has to be compiled with Q_ODBC_VERSION_2 defined. For the Oracle 9 ODBC driver (Windows), it is necessary to check @@ -368,9 +368,9 @@ The QPSQL driver supports version 7.3 and higher of the PostgreSQL server. We recommend that you use a client library from version 7.3.15, 7.4.13, - 8.0.8, 8.1.4 or more recent as these versions contain security fixes, and + 8.0.8, 8.1.4, or more recent, as these versions contain security fixes, and as the QPSQL driver might not build with older versions of the client - library depending on your platform. + library, depending on your platform. For more information about PostgreSQL visit \l http://www.postgresql.org. diff --git a/src/sql/doc/src/sql-programming.qdoc b/src/sql/doc/src/sql-programming.qdoc index 39381ff296..ece89a30ab 100644 --- a/src/sql/doc/src/sql-programming.qdoc +++ b/src/sql/doc/src/sql-programming.qdoc @@ -227,7 +227,7 @@ Databases, please refer to \l{Data Types for Qt-supported Database Systems} {this table}. - You can iterate back and forth using QSqlQuery::next(), + You can navigate within the dataset using QSqlQuery::next(), QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last(), and QSqlQuery::seek(). The current row index is returned by QSqlQuery::at(), and the total number of rows in the result set @@ -242,11 +242,10 @@ \snippet sqldatabase/sqldatabase.cpp 33 - If you iterate through a result set only using next() and seek() - with positive values, you can call - QSqlQuery::setForwardOnly(true) before calling exec(). This is an - easy optimization that will speed up the query significantly when - operating on large result sets. + If you navigate within a result set, and use next() and seek() + only for browsing forward, you can call QSqlQuery::setForwardOnly(true) + before calling exec(). This is an easy optimization that will speed up + the query significantly when operating on large result sets. \section2 Inserting, Updating, and Deleting Records @@ -592,7 +591,7 @@ QDataWidgetMapper operates on a specific database table, mapping items in the table on a row-by-row or column-by-column basis. As a result, - using QDataWidgetMapper with a SQL model is as simple as using it with + using QDataWidgetMapper with an SQL model is as simple as using it with any other table model. \image qdatawidgetmapper-simple.png -- cgit v1.2.3 From 9091a058bc61e297abea03edca322edcd658cc1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 28 Mar 2017 15:53:42 +0200 Subject: Android: Fix application state tracking - Make sure we don't process state changes before the platform plugin is completely created and registered. - Protect shared data with mutexes. - Don't update the application state from different threads. This was causing issues when testing run-time permission checks, when the application quickly switches state due to permission dialog being shown. In this case the states would be incorrectly delivered when the application was made active again. Change-Id: I3446eab9414ee5437cd788c27d65f808d1314aa5 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/androidjnimain.cpp | 42 ++++++++++++++-------- src/plugins/platforms/android/androidjnimain.h | 2 -- .../android/qandroidplatformintegration.cpp | 13 ++++--- .../android/qandroidplatformintegration.h | 7 ++-- .../platforms/android/qandroidplatformwindow.cpp | 5 --- 5 files changed, 40 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index bde7457c0b..e47dd91a3e 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -82,8 +82,8 @@ static jobject m_serviceObject = nullptr; static jmethodID m_setSurfaceGeometryMethodID = nullptr; static jmethodID m_destroySurfaceMethodID = nullptr; -static bool m_activityActive = true; // defaults to true because when the platform plugin is - // initialized, QtActivity::onResume() has already been called +static int m_pendingApplicationState = -1; +static QBasicMutex m_pendingAppStateMtx; static jclass m_bitmapClass = nullptr; static jmethodID m_createBitmapMethodID = nullptr; @@ -130,13 +130,22 @@ static const char m_qtTag[] = "Qt"; static const char m_classErrorMsg[] = "Can't find class \"%s\""; static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; +static void flushPendingApplicationState(); + namespace QtAndroid { void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration) { - m_surfacesMutex.lock(); + QMutexLocker lock(&m_surfacesMutex); m_androidPlatformIntegration = androidPlatformIntegration; - m_surfacesMutex.unlock(); + + // flush the pending state if necessary. + if (m_androidPlatformIntegration) { + flushPendingApplicationState(); + } else { + QMutexLocker locker(&m_pendingAppStateMtx); + m_pendingApplicationState = -1; + } } QAndroidPlatformIntegration *androidPlatformIntegration() @@ -215,12 +224,6 @@ namespace QtAndroid m_statusBarShowing = false; } - void setApplicationActive() - { - if (m_activityActive) - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); - } - jobject createBitmap(QImage img, JNIEnv *env) { if (!m_bitmapClass) @@ -446,6 +449,16 @@ namespace QtAndroid } // namespace QtAndroid +// Force an update of the pending application state (state set before the platform plugin was created) +static void flushPendingApplicationState() +{ + QMutexLocker locker(&m_pendingAppStateMtx); + if (m_pendingApplicationState == -1) + return; + + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(m_pendingApplicationState)); + m_pendingApplicationState = -1; +} static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/) { @@ -655,13 +668,14 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/) static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state) { - m_activityActive = (state == Qt::ApplicationActive); - - if (!m_main || !m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) { - QAndroidPlatformIntegration::setDefaultApplicationState(Qt::ApplicationState(state)); + if (!m_main || !QtAndroid::androidPlatformIntegration()) { + QMutexLocker locker(&m_pendingAppStateMtx); + m_pendingApplicationState = Qt::ApplicationState(state); return; } + flushPendingApplicationState(); + if (state == Qt::ApplicationActive) QtAndroidPrivate::handleResume(); else if (state == Qt::ApplicationInactive) diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 218e52ccc1..170596082d 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -85,8 +85,6 @@ namespace QtAndroid jobject activity(); jobject service(); - void setApplicationActive(); - void showStatusBar(); void hideStatusBar(); diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index de9e27e595..44b4668585 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -80,8 +80,6 @@ int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71; Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation; Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation; -Qt::ApplicationState QAndroidPlatformIntegration::m_defaultApplicationState = Qt::ApplicationActive; - bool QAndroidPlatformIntegration::m_showPasswordEnabled = false; void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) @@ -120,6 +118,12 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA return 0; } +void QAndroidPlatformNativeInterface::customEvent(QEvent *event) +{ + if (event->type() == QEvent::User) + QtAndroid::setAndroidPlatformIntegration(static_cast(QGuiApplicationPrivate::platformIntegration())); +} + QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶mList) : m_touchDevice(nullptr) #ifndef QT_NO_ACCESSIBILITY @@ -147,7 +151,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight)); m_mainThread = QThread::currentThread(); - QtAndroid::setAndroidPlatformIntegration(this); m_androidFDB = new QAndroidPlatformFontDatabase(); m_androidPlatformServices = new QAndroidPlatformServices(); @@ -210,7 +213,9 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ } } - QGuiApplicationPrivate::instance()->setApplicationState(m_defaultApplicationState); + // We can't safely notify the jni bridge that we're up and running just yet, so let's postpone + // it for now. + QCoreApplication::postEvent(m_androidPlatformNativeInterface, new QEvent(QEvent::User)); } static bool needsBasicRenderloopWorkaround() diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index 2337801250..208bb705b7 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -65,6 +65,9 @@ class QAndroidPlatformNativeInterface: public QPlatformNativeInterface public: void *nativeResourceForIntegration(const QByteArray &resource) override; std::shared_ptr m_androidStyle; + +protected: + void customEvent(QEvent *event) override; }; class QAndroidPlatformIntegration : public QPlatformIntegration @@ -121,7 +124,6 @@ public: QTouchDevice *touchDevice() const { return m_touchDevice; } void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; } - static void setDefaultApplicationState(Qt::ApplicationState applicationState) { m_defaultApplicationState = applicationState; } private: EGLDisplay m_eglDisplay; @@ -140,9 +142,6 @@ private: static Qt::ScreenOrientation m_orientation; static Qt::ScreenOrientation m_nativeOrientation; - - static Qt::ApplicationState m_defaultApplicationState; - static bool m_showPasswordEnabled; QPlatformFontDatabase *m_androidFDB; diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 97a1f30a35..424cfefc6c 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -96,11 +96,6 @@ void QAndroidPlatformWindow::setVisible(bool visible) QRect availableGeometry = screen()->availableGeometry(); if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) QPlatformWindow::setVisible(visible); - - // The Android Activity is activated before Qt is initialized, causing the application state to - // never be set to 'active'. We explicitly set this state when the first window becomes visible. - if (visible) - QtAndroid::setApplicationActive(); } void QAndroidPlatformWindow::setWindowState(Qt::WindowState state) -- cgit v1.2.3 From e893e657e5c976f96e7e627ca90531934129bf4b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 28 Feb 2017 14:11:44 +0100 Subject: configure: fix detection of xcb extensions - Properly detect xcb-render and xkb features. a) when -qt-xcb, use bundled versions b) when -system-xcb, detect from system - Be consistent with other features (jpeg, png) in "enable"/"disable" field handling. - And move the "xkb" feature higer up in configure.json. It is an X11 extension, so keep them all together (instead of grouping it with libxkbcommon). Task-number: QTBUG-59064 Change-Id: I60f95fb37060b8abde4c611cdef178ba3795982c Reviewed-by: Oswald Buddenhagen --- src/gui/configure.json | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gui/configure.json b/src/gui/configure.json index 88c9858a34..1c4a499298 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -224,7 +224,7 @@ ] }, "xcb_syslibs": { - "label": "XCB (secondary)", + "label": "XCB (extensions)", "test": "qpa/xcb-syslibs", "sources": [ { "type": "pkgConfig", @@ -701,11 +701,11 @@ "output": [ "privateFeature" ] }, "system-xcb": { - "label": "Using system provided XCB libraries", - "enable": "input.xcb == 'system' || input.xcb == 'yes'", - "disable": "input.xcb == 'qt' || input.xcb == 'no'", + "label": "Using system-provided XCB libraries", + "enable": "input.xcb == 'system'", + "disable": "input.xcb == 'qt'", "autoDetect": "!config.darwin", - "condition": "libs.xcb && libs.xcb_syslibs", + "condition": "features.xcb && libs.xcb_syslibs", "output": [ "privateFeature" ] }, "x11-prefix": { @@ -721,8 +721,14 @@ }, "xcb-render": { "label": "XCB render", - "emitIf": "features.system-xcb", - "condition": "libs.xcb_render", + "emitIf": "features.xcb", + "condition": "!features.system-xcb || libs.xcb_render", + "output": [ "privateFeature" ] + }, + "xkb": { + "label": "XCB XKB", + "emitIf": "features.xcb", + "condition": "!features.system-xcb || libs.xcb_xkb", "output": [ "privateFeature" ] }, "xcb-xlib": { @@ -739,6 +745,7 @@ }, "xinput2": { "label": "Xinput2", + "emitIf": "features.xcb", "condition": "libs.xinput2", "output": [ "privateFeature" ] }, @@ -755,11 +762,6 @@ "condition": "libs.xkbcommon_x11", "output": [ "privateFeature" ] }, - "xkb": { - "label": "XCB XKB", - "condition": "features.system-xcb && libs.xcb_xkb", - "output": [ "privateFeature" ] - }, "xkb-config-root": { "label": "XKB config root", "emitIf": "features.xcb", -- cgit v1.2.3