Merge remote-tracking branch 'origin/5.12' into dev

Change-Id: Ic3ffc44d61448a44353c004b9f6703786cc1b213
This commit is contained in:
Qt Forward Merge Bot 2018-09-16 01:00:13 +02:00
commit 4e0fcc6ffc
52 changed files with 153 additions and 42 deletions

View File

@ -39,7 +39,7 @@
The heavy computation here is the Mandelbrot set, probably the
world's most famous fractal. These days, while sophisticated
programs such as \l{http://xaos.sourceforge.net/}{XaoS} that provide real-time zooming in the
programs such as \l{http://matek.hu/xaos/doku.php}{XaoS} that provide real-time zooming in the
Mandelbrot set, the standard Mandelbrot algorithm is just slow
enough for our purposes.
@ -201,7 +201,7 @@
\snippet threads/mandelbrot/renderthread.cpp 9
Once we're done with all the iterations, we call
QWaitCondition::wait() to put the thread to sleep by calling,
QWaitCondition::wait() to put the thread to sleep,
unless \c restart is \c true. There's no use in keeping a worker
thread looping indefinitely while there's nothing to do.
@ -232,7 +232,7 @@
\snippet threads/mandelbrot/mandelbrotwidget.cpp 0
The implementation starts with a few contants that we'll need
The implementation starts with a few constants that we'll need
later on.
\snippet threads/mandelbrot/mandelbrotwidget.cpp 1
@ -256,15 +256,15 @@
slot later on. Qt knows how to take of copy of many C++ and Qt
types, but QImage isn't one of them. We must therefore call the
template function qRegisterMetaType() before we can use QImage
as parameter in queued connections.
as a parameter in queued connections.
\snippet threads/mandelbrot/mandelbrotwidget.cpp 2
\snippet threads/mandelbrot/mandelbrotwidget.cpp 3
\snippet threads/mandelbrot/mandelbrotwidget.cpp 4
In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling
the background with black. If we have nothing yet to paint (\c
pixmap is null), we print a message on the widget asking the user
the background with black. If we have nothing to paint yet (\c
pixmap is null), we display a message on the widget asking the user
to be patient and return from the function immediately.
\snippet threads/mandelbrot/mandelbrotwidget.cpp 5
@ -293,7 +293,7 @@
Notice that we rely on \c resizeEvent() being automatically
called by Qt when the widget is shown the first time to generate
the image the very first time.
the initial image.
\snippet threads/mandelbrot/mandelbrotwidget.cpp 11
@ -307,7 +307,7 @@
control the zoom level. QWheelEvent::delta() returns the angle of
the wheel mouse movement, in eights of a degree. For most mice,
one wheel step corresponds to 15 degrees. We find out how many
mouse steps we have and determine the zoom factor in consequence.
mouse steps we have and determine the resulting zoom factor.
For example, if we have two wheel steps in the positive direction
(i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor
to the second power, i.e. 0.8 * 0.8 = 0.64.

View File

@ -4,8 +4,7 @@ CONFIG += no_docs_target
SUBDIRS = \
corelib \
embedded \
qpa \
touch
qpa
qtHaveModule(dbus): SUBDIRS += dbus
qtHaveModule(network): SUBDIRS += network

View File

@ -4,5 +4,5 @@ SOURCES += main.cpp
FORMS += dials.ui
# install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/dials
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/dials
INSTALLS += target

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -29,7 +29,7 @@
\example touch/dials
\title Touch Dials Example
\ingroup touchinputexamples
\brief Shows how to apply touch to a set of standard Qt widgets
\brief Shows how to apply touch to a set of standard Qt widgets.
The Touch Dials example shows how to apply touch to a set of
standard Qt widgets.

View File

@ -29,7 +29,7 @@
\example touch/fingerpaint
\title Finger Paint Example
\ingroup touchinputexamples
\brief Shows the use of a touchscreen to make a simple painting application
\brief Shows the use of a touchscreen to make a simple painting application.
The Finger Paint example shows the use of a touchscreen with a custom widget
to create a simple painting application.

View File

@ -9,5 +9,5 @@ SOURCES = main.cpp \
scribblearea.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/fingerpaint
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/fingerpaint
INSTALLS += target

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -29,7 +29,7 @@
\example touch/knobs
\title Touch Knobs Example
\ingroup touchinputexamples
\brief Shows how to create custom controls that accept touch input
\brief Shows how to create custom controls that accept touch input.
The Touch Knobs example shows how to create custom controls that
accept touch input.

View File

@ -4,5 +4,5 @@ HEADERS = knob.h
SOURCES = main.cpp knob.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/knobs
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/knobs
INSTALLS += target

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -29,7 +29,7 @@
\example touch/pinchzoom
\title Pinch Zoom Example
\ingroup touchinputexamples
\brief Shows how to recognize a gesture
\brief Shows how to recognize a gesture.
The Pinch Zoom example shows how to use low-level touch information
to recognize a gesture.

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -12,5 +12,5 @@ RESOURCES += \
mice.qrc
# install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/pinchzoom
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/pinchzoom
INSTALLS += target

View File

@ -19,6 +19,7 @@ SUBDIRS = \
scroller \
statemachine \
tools \
touch \
tutorials \
widgets

View File

@ -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

View File

@ -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) {

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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

View File

@ -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();
const int localPos = query->value(Qt::ImCursorPosition).toInt();
if (!(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase))
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)

View File

@ -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];
}

View File

@ -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()

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -19,6 +19,7 @@ winrt
[graphicsViewClipping]
windows
winrt
rhel-7.4 ci
[glFBOUseInGLWidget]
windows
winrt

View File

@ -197,6 +197,8 @@ private slots:
void sqlite_enableRegexp_data() { generic_data("QSQLITE"); }
void sqlite_enableRegexp();
void sqlite_openError();
private:
void createTestTables(QSqlDatabase db);
void dropTestTables(QSqlDatabase db);
@ -2332,6 +2334,22 @@ void tst_QSqlDatabase::sqlite_enableRegexp()
QFAIL_SQL(q, next());
}
void tst_QSqlDatabase::sqlite_openError()
{
// see QTBUG-70506
if (!QSqlDatabase::drivers().contains("QSQLITE"))
QSKIP("Database driver QSQLITE not available");
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite_openError");
db.setDatabaseName("/doesnotexist/foo.sqlite");
QVERIFY(db.isValid());
QVERIFY(!db.open());
QSqlError error = db.lastError();
QCOMPARE(error.nativeErrorCode(), "14"); // SQLITE_CANTOPEN
QCOMPARE(error.databaseText(), "unable to open database file");
}
void tst_QSqlDatabase::cloneDatabase()
{
QFETCH(QString, dbName);

View File

@ -0,0 +1,2 @@
[QTBUG4419_lineEditSelectAll]
osx

View File

@ -0,0 +1,2 @@
[editingFinished]
*

View File

@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qmdisubwindow
QT += widgets testlib
QT += widgets widgets-private testlib
INCLUDEPATH += .
SOURCES += tst_qmdisubwindow.cpp
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII

View File

@ -30,6 +30,7 @@
#include <QtTest/QtTest>
#include "qmdisubwindow.h"
#include "private/qmdisubwindow_p.h"
#include "qmdiarea.h"
#include <QLayout>
@ -723,7 +724,9 @@ void tst_QMdiSubWindow::setOpaqueResizeAndMove()
resizeSpy.clear();
QCOMPARE(resizeSpy.count(), 0);
QTest::qWait(250); // delayed update of dirty regions
// we need to wait for the resizeTimer to make sure updateDirtyRegions is called
auto priv = static_cast<QMdiSubWindowPrivate*>(qt_widget_private(window));
QTRY_COMPARE(priv->resizeTimerId, -1);
// Enter resize mode.
int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2;