summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-09-16 01:00:13 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-09-16 01:00:13 +0200
commit4e0fcc6ffc2840f08478410a6f90c3044af247b3 (patch)
tree1442b0919f09d9fc6f7e02fd3a0ab783aefe265b /src
parent6723155bc768790f14d97a61b74b01e7465ba199 (diff)
parent6bb0cbc6865911c31f5edee7c24f270d265bd46d (diff)
Merge remote-tracking branch 'origin/5.12' into dev
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qnamespace.qdoc10
-rw-r--r--src/corelib/kernel/qmetaobject.cpp3
-rw-r--r--src/corelib/kernel/qmetatype.cpp2
-rw-r--r--src/gui/image/qbmphandler.cpp2
-rw-r--r--src/gui/image/qimage.h2
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm10
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp49
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h2
-rw-r--r--src/plugins/sqldrivers/odbc/qsql_odbc.cpp2
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp19
14 files changed, 108 insertions, 23 deletions
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 37144dcf17..42009e0b5e 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -245,7 +245,10 @@
QEvent::MouseMove, QEvent::TouchUpdate, and changes in window size and
position will be combined whenever they occur more frequently than the
application handles them, so that they don't accumulate and overwhelm the
- application later. On other platforms, the default is false.
+ application later.
+ On Windows 8 and above the default value is also true, but it only applies
+ to touch events. Mouse and window events remain unaffected by this flag.
+ On other platforms, the default is false.
(In the future, the compression feature may be implemented across platforms.)
You can test the attribute to see whether compression is enabled.
If your application needs to handle all events with no compression,
@@ -256,8 +259,9 @@
\value AA_CompressTabletEvents Enables compression of input events from tablet devices.
Notice that AA_CompressHighFrequencyEvents must be true for events compression
- to be enabled, and that this flag extends the former to tablet events. Its default
- value is false.
+ to be enabled, and that this flag extends the former to tablet events.
+ Currently supported on the X11 windowing system, Windows 8 and above.
+ The default value is false.
This value was added in Qt 5.10.
\value AA_DontCheckOpenGLContextThreadAffinity When making a context
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 6c17535f07..a6ee12ede1 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -970,9 +970,9 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co
int QMetaObject::indexOfEnumerator(const char *name) const
{
const QMetaObject *m = this;
- const int intsPerEnum = priv(m->d.data)->revision >= 8 ? 5 : 4;
while (m) {
const QMetaObjectPrivate *d = priv(m->d.data);
+ const int intsPerEnum = d->revision >= 8 ? 5 : 4;
for (int i = d->enumeratorCount - 1; i >= 0; --i) {
const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i]);
if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
@@ -986,6 +986,7 @@ int QMetaObject::indexOfEnumerator(const char *name) const
m = this;
while (m) {
const QMetaObjectPrivate *d = priv(m->d.data);
+ const int intsPerEnum = d->revision >= 8 ? 5 : 4;
for (int i = d->enumeratorCount - 1; i >= 0; --i) {
const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i + 1]);
if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 82952919dd..eb67544f21 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -1058,7 +1058,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
\internal
\since 5.12
- Registers a user type for marshalling, with \a typeName, a \a
+ Registers a user type for marshalling, with \a typeName, a
\a destructor, a \a constructor, and a \a size. Returns the
type's handle, or -1 if the type could not be registered.
*/
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 587f375ce7..5dff4ab0ac 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -188,6 +188,8 @@ static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi)
if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
(nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)))
return false; // weird compression type
+ if (bi.biWidth < 0 || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384)
+ return false;
return true;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 7764c19452..4b7a3b1ead 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -334,7 +334,7 @@ public:
static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW;
static QImage::Format toImageFormat(QPixelFormat format) Q_DECL_NOTHROW;
- // Platform spesific conversion functions
+ // Platform specific conversion functions
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED;
#endif
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index ea3e9c1441..c5cd0b92d9 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -58,6 +58,7 @@
#include <private/qhighdpiscaling_p.h>
#include <QTextCharFormat>
+#include <QTextBoundaryFinder>
#include <QDebug>
@@ -1020,8 +1021,19 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
return res;
const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt();
-
- if (!(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase))
+ const int localPos = query->value(Qt::ImCursorPosition).toInt();
+
+ bool atWordBoundary = (localPos == 0);
+ if (!atWordBoundary) {
+ QString surroundingText = query->value(Qt::ImSurroundingText).toString();
+ surroundingText.truncate(localPos);
+ // Add a character to see if it is at the end of the sentence or not
+ QTextBoundaryFinder finder(QTextBoundaryFinder::Sentence, surroundingText + QLatin1Char('A'));
+ finder.setPosition(localPos);
+ if (finder.isAtBoundary())
+ atWordBoundary = finder.isAtBoundary();
+ }
+ if (atWordBoundary && !(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase))
res |= CAP_MODE_SENTENCES;
if (qtInputMethodHints & Qt::ImhUppercaseOnly)
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index f11016679a..069429796e 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -393,8 +393,10 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
return true;
}
-// NSOpenGLContext is not re-entrant (https://openradar.appspot.com/37064579)
-static QMutex s_contextMutex;
+// NSOpenGLContext is not re-entrant. Even when using separate contexts per thread,
+// view, and window, calls into the API will still deadlock. For more information
+// see https://openradar.appspot.com/37064579
+static QMutex s_reentrancyMutex;
void QCocoaGLContext::update()
{
@@ -403,7 +405,7 @@ void QCocoaGLContext::update()
// render-loop that doesn't return to one of the outer pools.
QMacAutoReleasePool pool;
- QMutexLocker locker(&s_contextMutex);
+ QMutexLocker locker(&s_reentrancyMutex);
qCInfo(lcQpaOpenGLContext) << "Updating" << m_context << "for" << m_context.view;
[m_context update];
}
@@ -422,7 +424,7 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
return;
}
- QMutexLocker locker(&s_contextMutex);
+ QMutexLocker locker(&s_reentrancyMutex);
[m_context flushBuffer];
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 03bb1bee48..373758b49e 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -201,7 +201,9 @@ void QWindowsUser32DLL::init()
getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects");
getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo");
getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo");
+ getPointerFrameTouchInfoHistory = (GetPointerFrameTouchInfoHistory)library.resolve("GetPointerFrameTouchInfoHistory");
getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo");
+ getPointerPenInfoHistory = (GetPointerPenInfoHistory)library.resolve("GetPointerPenInfoHistory");
skipPointerFrameMessages = (SkipPointerFrameMessages)library.resolve("SkipPointerFrameMessages");
}
@@ -216,8 +218,8 @@ void QWindowsUser32DLL::init()
bool QWindowsUser32DLL::supportsPointerApi()
{
return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects
- && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo
- && skipPointerFrameMessages;
+ && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerFrameTouchInfoHistory
+ && getPointerPenInfo && getPointerPenInfoHistory && skipPointerFrameMessages;
}
void QWindowsShcoreDLL::init()
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 8102e0bf19..622c729a10 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -92,7 +92,9 @@ struct QWindowsUser32DLL
typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *);
typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID);
typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *GetPointerFrameTouchInfoHistory)(UINT32, UINT32 *, UINT32 *, PVOID);
typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID);
typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32);
typedef BOOL (WINAPI *SetProcessDPIAware)();
typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
@@ -110,7 +112,9 @@ struct QWindowsUser32DLL
GetPointerDeviceRects getPointerDeviceRects = nullptr;
GetPointerTouchInfo getPointerTouchInfo = nullptr;
GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr;
+ GetPointerFrameTouchInfoHistory getPointerFrameTouchInfoHistory = nullptr;
GetPointerPenInfo getPointerPenInfo = nullptr;
+ GetPointerPenInfoHistory getPointerPenInfoHistory = nullptr;
SkipPointerFrameMessages skipPointerFrameMessages = nullptr;
// Windows Vista onwards
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 0694435427..7d621126b9 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -236,7 +236,9 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness);
QWindowsFontDatabase::setFontOptions(m_options);
- if (!m_context.initPointer(m_options)) {
+ if (m_context.initPointer(m_options)) {
+ QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
+ } else {
m_context.initTablet(m_options);
if (tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(tabletAbsoluteRange);
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index d8918d1b3d..7ead14822a 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -106,6 +106,32 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
return false;
}
+
+ if (!pointerCount)
+ return false;
+
+ // The history count is the same for all the touchpoints in touchInfo
+ quint32 historyCount = touchInfo[0].pointerInfo.historyCount;
+ // dispatch any skipped frames if event compression is disabled by the app
+ if (historyCount > 1 && !QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) {
+ touchInfo.resize(pointerCount * historyCount);
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId,
+ &historyCount,
+ &pointerCount,
+ touchInfo.data())) {
+ qWarning() << "GetPointerFrameTouchInfoHistory() failed:" << qt_error_string();
+ return false;
+ }
+
+ // history frames are returned with the most recent frame first so we iterate backwards
+ bool result = true;
+ for (auto it = touchInfo.rbegin(), end = touchInfo.rend(); it != end; it += pointerCount) {
+ result &= translateTouchEvent(window, hwnd, et, msg,
+ &(*(it + (pointerCount - 1))), pointerCount);
+ }
+ return result;
+ }
+
return translateTouchEvent(window, hwnd, et, msg, touchInfo.data(), pointerCount);
}
case QT_PT_PEN: {
@@ -114,6 +140,29 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
qWarning() << "GetPointerPenInfo() failed:" << qt_error_string();
return false;
}
+
+ quint32 historyCount = penInfo.pointerInfo.historyCount;
+ // dispatch any skipped frames if generic or tablet event compression is disabled by the app
+ if (historyCount > 1
+ && (!QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)
+ || !QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents))) {
+ QVarLengthArray<POINTER_PEN_INFO, 10> penInfoHistory(historyCount);
+
+ if (!QWindowsContext::user32dll.getPointerPenInfoHistory(pointerId,
+ &historyCount,
+ penInfoHistory.data())) {
+ qWarning() << "GetPointerPenInfoHistory() failed:" << qt_error_string();
+ return false;
+ }
+
+ // history frames are returned with the most recent frame first so we iterate backwards
+ bool result = true;
+ for (auto it = penInfoHistory.rbegin(), end = penInfoHistory.rend(); it != end; ++it) {
+ result &= translatePenEvent(window, hwnd, et, msg, &(*(it)));
+ }
+ return result;
+ }
+
return translatePenEvent(window, hwnd, et, msg, &penInfo);
}
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index b0c36e61b0..94f8a8876a 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -414,6 +414,8 @@ public:
bool imageNeedsEndianSwap() const
{
+ if (!hasShm())
+ return false; // The non-Shm path does its own swapping
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
return m_setup->image_byte_order != XCB_IMAGE_ORDER_MSB_FIRST;
#else
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
index daf9686b5e..1fbbcd0ef1 100644
--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
@@ -1307,7 +1307,7 @@ QVariant QODBCResult::data(int field)
bool QODBCResult::isNull(int field)
{
Q_D(const QODBCResult);
- if (field < 0 || field > d->fieldCache.size())
+ if (field < 0 || field >= d->fieldCache.size())
return true;
if (field <= d->fieldCacheIdx) {
// since there is no good way to find out whether the value is NULL
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index 81b5776a7c..f1a003ddcd 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -106,7 +106,7 @@ static QVariant::Type qGetColumnType(const QString &tpName)
}
static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::ErrorType type,
- int errorCode = -1)
+ int errorCode)
{
return QSqlError(descr,
QString(reinterpret_cast<const QChar *>(sqlite3_errmsg16(access))),
@@ -772,7 +772,9 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
openMode |= SQLITE_OPEN_NOMUTEX;
- if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) {
+ const int res = sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL);
+
+ if (res == SQLITE_OK) {
sqlite3_busy_timeout(d->access, timeOut);
setOpen(true);
setOpenError(false);
@@ -785,14 +787,15 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
#endif
return true;
} else {
+ setLastError(qMakeError(d->access, tr("Error opening database"),
+ QSqlError::ConnectionError, res));
+ setOpenError(true);
+
if (d->access) {
sqlite3_close(d->access);
d->access = 0;
}
- setLastError(qMakeError(d->access, tr("Error opening database"),
- QSqlError::ConnectionError));
- setOpenError(true);
return false;
}
}
@@ -809,8 +812,10 @@ void QSQLiteDriver::close()
sqlite3_update_hook(d->access, NULL, NULL);
}
- if (sqlite3_close(d->access) != SQLITE_OK)
- setLastError(qMakeError(d->access, tr("Error closing database"), QSqlError::ConnectionError));
+ const int res = sqlite3_close(d->access);
+
+ if (res != SQLITE_OK)
+ setLastError(qMakeError(d->access, tr("Error closing database"), QSqlError::ConnectionError, res));
d->access = 0;
setOpen(false);
setOpenError(false);