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 The heavy computation here is the Mandelbrot set, probably the
world's most famous fractal. These days, while sophisticated 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 Mandelbrot set, the standard Mandelbrot algorithm is just slow
enough for our purposes. enough for our purposes.
@ -201,7 +201,7 @@
\snippet threads/mandelbrot/renderthread.cpp 9 \snippet threads/mandelbrot/renderthread.cpp 9
Once we're done with all the iterations, we call 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 unless \c restart is \c true. There's no use in keeping a worker
thread looping indefinitely while there's nothing to do. thread looping indefinitely while there's nothing to do.
@ -232,7 +232,7 @@
\snippet threads/mandelbrot/mandelbrotwidget.cpp 0 \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. later on.
\snippet threads/mandelbrot/mandelbrotwidget.cpp 1 \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 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 types, but QImage isn't one of them. We must therefore call the
template function qRegisterMetaType() before we can use QImage 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 2
\snippet threads/mandelbrot/mandelbrotwidget.cpp 3 \snippet threads/mandelbrot/mandelbrotwidget.cpp 3
\snippet threads/mandelbrot/mandelbrotwidget.cpp 4 \snippet threads/mandelbrot/mandelbrotwidget.cpp 4
In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling
the background with black. If we have nothing yet to paint (\c the background with black. If we have nothing to paint yet (\c
pixmap is null), we print a message on the widget asking the user pixmap is null), we display a message on the widget asking the user
to be patient and return from the function immediately. to be patient and return from the function immediately.
\snippet threads/mandelbrot/mandelbrotwidget.cpp 5 \snippet threads/mandelbrot/mandelbrotwidget.cpp 5
@ -293,7 +293,7 @@
Notice that we rely on \c resizeEvent() being automatically Notice that we rely on \c resizeEvent() being automatically
called by Qt when the widget is shown the first time to generate 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 \snippet threads/mandelbrot/mandelbrotwidget.cpp 11
@ -307,7 +307,7 @@
control the zoom level. QWheelEvent::delta() returns the angle of control the zoom level. QWheelEvent::delta() returns the angle of
the wheel mouse movement, in eights of a degree. For most mice, the wheel mouse movement, in eights of a degree. For most mice,
one wheel step corresponds to 15 degrees. We find out how many 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 For example, if we have two wheel steps in the positive direction
(i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor (i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor
to the second power, i.e. 0.8 * 0.8 = 0.64. to the second power, i.e. 0.8 * 0.8 = 0.64.

View File

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

View File

@ -4,5 +4,5 @@ SOURCES += main.cpp
FORMS += dials.ui FORMS += dials.ui
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/dials target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/dials
INSTALLS += target 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 \example touch/dials
\title Touch Dials Example \title Touch Dials Example
\ingroup touchinputexamples \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 The Touch Dials example shows how to apply touch to a set of
standard Qt widgets. standard Qt widgets.

View File

@ -29,7 +29,7 @@
\example touch/fingerpaint \example touch/fingerpaint
\title Finger Paint Example \title Finger Paint Example
\ingroup touchinputexamples \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 The Finger Paint example shows the use of a touchscreen with a custom widget
to create a simple painting application. to create a simple painting application.

View File

@ -9,5 +9,5 @@ SOURCES = main.cpp \
scribblearea.cpp scribblearea.cpp
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/fingerpaint target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/fingerpaint
INSTALLS += target 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 \example touch/knobs
\title Touch Knobs Example \title Touch Knobs Example
\ingroup touchinputexamples \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 The Touch Knobs example shows how to create custom controls that
accept touch input. accept touch input.

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -29,7 +29,7 @@
\example touch/pinchzoom \example touch/pinchzoom
\title Pinch Zoom Example \title Pinch Zoom Example
\ingroup touchinputexamples \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 The Pinch Zoom example shows how to use low-level touch information
to recognize a gesture. 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 mice.qrc
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/touch/pinchzoom target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/pinchzoom
INSTALLS += target INSTALLS += target

View File

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

View File

@ -245,7 +245,10 @@
QEvent::MouseMove, QEvent::TouchUpdate, and changes in window size and QEvent::MouseMove, QEvent::TouchUpdate, and changes in window size and
position will be combined whenever they occur more frequently than the position will be combined whenever they occur more frequently than the
application handles them, so that they don't accumulate and overwhelm 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.) (In the future, the compression feature may be implemented across platforms.)
You can test the attribute to see whether compression is enabled. You can test the attribute to see whether compression is enabled.
If your application needs to handle all events with no compression, 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. \value AA_CompressTabletEvents Enables compression of input events from tablet devices.
Notice that AA_CompressHighFrequencyEvents must be true for events compression 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 to be enabled, and that this flag extends the former to tablet events.
value is false. Currently supported on the X11 windowing system, Windows 8 and above.
The default value is false.
This value was added in Qt 5.10. This value was added in Qt 5.10.
\value AA_DontCheckOpenGLContextThreadAffinity When making a context \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 int QMetaObject::indexOfEnumerator(const char *name) const
{ {
const QMetaObject *m = this; const QMetaObject *m = this;
const int intsPerEnum = priv(m->d.data)->revision >= 8 ? 5 : 4;
while (m) { while (m) {
const QMetaObjectPrivate *d = priv(m->d.data); const QMetaObjectPrivate *d = priv(m->d.data);
const int intsPerEnum = d->revision >= 8 ? 5 : 4;
for (int i = d->enumeratorCount - 1; i >= 0; --i) { for (int i = d->enumeratorCount - 1; i >= 0; --i) {
const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i]); const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i]);
if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
@ -986,6 +986,7 @@ int QMetaObject::indexOfEnumerator(const char *name) const
m = this; m = this;
while (m) { while (m) {
const QMetaObjectPrivate *d = priv(m->d.data); const QMetaObjectPrivate *d = priv(m->d.data);
const int intsPerEnum = d->revision >= 8 ? 5 : 4;
for (int i = d->enumeratorCount - 1; i >= 0; --i) { for (int i = d->enumeratorCount - 1; i >= 0; --i) {
const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i + 1]); const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i + 1]);
if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { 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 \internal
\since 5.12 \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 \a destructor, a \a constructor, and a \a size. Returns the
type's handle, or -1 if the type could not be registered. 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) || if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
(nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS))) (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)))
return false; // weird compression type return false; // weird compression type
if (bi.biWidth < 0 || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384)
return false;
return true; return true;
} }

View File

@ -334,7 +334,7 @@ public:
static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW; static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW;
static QImage::Format toImageFormat(QPixelFormat 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) #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED; CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED;
#endif #endif

View File

@ -58,6 +58,7 @@
#include <private/qhighdpiscaling_p.h> #include <private/qhighdpiscaling_p.h>
#include <QTextCharFormat> #include <QTextCharFormat>
#include <QTextBoundaryFinder>
#include <QDebug> #include <QDebug>
@ -1020,8 +1021,19 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
return res; return res;
const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt(); 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; res |= CAP_MODE_SENTENCES;
if (qtInputMethodHints & Qt::ImhUppercaseOnly) if (qtInputMethodHints & Qt::ImhUppercaseOnly)

View File

@ -393,8 +393,10 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
return true; return true;
} }
// NSOpenGLContext is not re-entrant (https://openradar.appspot.com/37064579) // NSOpenGLContext is not re-entrant. Even when using separate contexts per thread,
static QMutex s_contextMutex; // 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() void QCocoaGLContext::update()
{ {
@ -403,7 +405,7 @@ void QCocoaGLContext::update()
// render-loop that doesn't return to one of the outer pools. // render-loop that doesn't return to one of the outer pools.
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
QMutexLocker locker(&s_contextMutex); QMutexLocker locker(&s_reentrancyMutex);
qCInfo(lcQpaOpenGLContext) << "Updating" << m_context << "for" << m_context.view; qCInfo(lcQpaOpenGLContext) << "Updating" << m_context << "for" << m_context.view;
[m_context update]; [m_context update];
} }
@ -422,7 +424,7 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
return; return;
} }
QMutexLocker locker(&s_contextMutex); QMutexLocker locker(&s_reentrancyMutex);
[m_context flushBuffer]; [m_context flushBuffer];
} }

View File

@ -201,7 +201,9 @@ void QWindowsUser32DLL::init()
getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects"); getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects");
getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo"); getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo");
getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo"); getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo");
getPointerFrameTouchInfoHistory = (GetPointerFrameTouchInfoHistory)library.resolve("GetPointerFrameTouchInfoHistory");
getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo"); getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo");
getPointerPenInfoHistory = (GetPointerPenInfoHistory)library.resolve("GetPointerPenInfoHistory");
skipPointerFrameMessages = (SkipPointerFrameMessages)library.resolve("SkipPointerFrameMessages"); skipPointerFrameMessages = (SkipPointerFrameMessages)library.resolve("SkipPointerFrameMessages");
} }
@ -216,8 +218,8 @@ void QWindowsUser32DLL::init()
bool QWindowsUser32DLL::supportsPointerApi() bool QWindowsUser32DLL::supportsPointerApi()
{ {
return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects
&& getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerFrameTouchInfoHistory
&& skipPointerFrameMessages; && getPointerPenInfo && getPointerPenInfoHistory && skipPointerFrameMessages;
} }
void QWindowsShcoreDLL::init() void QWindowsShcoreDLL::init()

View File

@ -92,7 +92,9 @@ struct QWindowsUser32DLL
typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *); typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *);
typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID);
typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, 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 *GetPointerPenInfo)(UINT32, PVOID);
typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID);
typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32); typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32);
typedef BOOL (WINAPI *SetProcessDPIAware)(); typedef BOOL (WINAPI *SetProcessDPIAware)();
typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND); typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
@ -110,7 +112,9 @@ struct QWindowsUser32DLL
GetPointerDeviceRects getPointerDeviceRects = nullptr; GetPointerDeviceRects getPointerDeviceRects = nullptr;
GetPointerTouchInfo getPointerTouchInfo = nullptr; GetPointerTouchInfo getPointerTouchInfo = nullptr;
GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr; GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr;
GetPointerFrameTouchInfoHistory getPointerFrameTouchInfoHistory = nullptr;
GetPointerPenInfo getPointerPenInfo = nullptr; GetPointerPenInfo getPointerPenInfo = nullptr;
GetPointerPenInfoHistory getPointerPenInfoHistory = nullptr;
SkipPointerFrameMessages skipPointerFrameMessages = nullptr; SkipPointerFrameMessages skipPointerFrameMessages = nullptr;
// Windows Vista onwards // Windows Vista onwards

View File

@ -236,7 +236,9 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness); m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness);
QWindowsFontDatabase::setFontOptions(m_options); 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); m_context.initTablet(m_options);
if (tabletAbsoluteRange >= 0) if (tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(tabletAbsoluteRange); m_context.setTabletAbsoluteRange(tabletAbsoluteRange);

View File

@ -106,6 +106,32 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string(); qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
return false; 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); return translateTouchEvent(window, hwnd, et, msg, touchInfo.data(), pointerCount);
} }
case QT_PT_PEN: { case QT_PT_PEN: {
@ -114,6 +140,29 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
qWarning() << "GetPointerPenInfo() failed:" << qt_error_string(); qWarning() << "GetPointerPenInfo() failed:" << qt_error_string();
return false; 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); return translatePenEvent(window, hwnd, et, msg, &penInfo);
} }
} }

View File

@ -414,6 +414,8 @@ public:
bool imageNeedsEndianSwap() const bool imageNeedsEndianSwap() const
{ {
if (!hasShm())
return false; // The non-Shm path does its own swapping
#if Q_BYTE_ORDER == Q_BIG_ENDIAN #if Q_BYTE_ORDER == Q_BIG_ENDIAN
return m_setup->image_byte_order != XCB_IMAGE_ORDER_MSB_FIRST; return m_setup->image_byte_order != XCB_IMAGE_ORDER_MSB_FIRST;
#else #else

View File

@ -1307,7 +1307,7 @@ QVariant QODBCResult::data(int field)
bool QODBCResult::isNull(int field) bool QODBCResult::isNull(int field)
{ {
Q_D(const QODBCResult); Q_D(const QODBCResult);
if (field < 0 || field > d->fieldCache.size()) if (field < 0 || field >= d->fieldCache.size())
return true; return true;
if (field <= d->fieldCacheIdx) { if (field <= d->fieldCacheIdx) {
// since there is no good way to find out whether the value is NULL // 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, static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::ErrorType type,
int errorCode = -1) int errorCode)
{ {
return QSqlError(descr, return QSqlError(descr,
QString(reinterpret_cast<const QChar *>(sqlite3_errmsg16(access))), 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; 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); sqlite3_busy_timeout(d->access, timeOut);
setOpen(true); setOpen(true);
setOpenError(false); setOpenError(false);
@ -785,14 +787,15 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
#endif #endif
return true; return true;
} else { } else {
setLastError(qMakeError(d->access, tr("Error opening database"),
QSqlError::ConnectionError, res));
setOpenError(true);
if (d->access) { if (d->access) {
sqlite3_close(d->access); sqlite3_close(d->access);
d->access = 0; d->access = 0;
} }
setLastError(qMakeError(d->access, tr("Error opening database"),
QSqlError::ConnectionError));
setOpenError(true);
return false; return false;
} }
} }
@ -809,8 +812,10 @@ void QSQLiteDriver::close()
sqlite3_update_hook(d->access, NULL, NULL); sqlite3_update_hook(d->access, NULL, NULL);
} }
if (sqlite3_close(d->access) != SQLITE_OK) const int res = sqlite3_close(d->access);
setLastError(qMakeError(d->access, tr("Error closing database"), QSqlError::ConnectionError));
if (res != SQLITE_OK)
setLastError(qMakeError(d->access, tr("Error closing database"), QSqlError::ConnectionError, res));
d->access = 0; d->access = 0;
setOpen(false); setOpen(false);
setOpenError(false); setOpenError(false);

View File

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

View File

@ -197,6 +197,8 @@ private slots:
void sqlite_enableRegexp_data() { generic_data("QSQLITE"); } void sqlite_enableRegexp_data() { generic_data("QSQLITE"); }
void sqlite_enableRegexp(); void sqlite_enableRegexp();
void sqlite_openError();
private: private:
void createTestTables(QSqlDatabase db); void createTestTables(QSqlDatabase db);
void dropTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db);
@ -2332,6 +2334,22 @@ void tst_QSqlDatabase::sqlite_enableRegexp()
QFAIL_SQL(q, next()); 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() void tst_QSqlDatabase::cloneDatabase()
{ {
QFETCH(QString, dbName); 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 CONFIG += testcase
TARGET = tst_qmdisubwindow TARGET = tst_qmdisubwindow
QT += widgets testlib QT += widgets widgets-private testlib
INCLUDEPATH += . INCLUDEPATH += .
SOURCES += tst_qmdisubwindow.cpp SOURCES += tst_qmdisubwindow.cpp
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII

View File

@ -30,6 +30,7 @@
#include <QtTest/QtTest> #include <QtTest/QtTest>
#include "qmdisubwindow.h" #include "qmdisubwindow.h"
#include "private/qmdisubwindow_p.h"
#include "qmdiarea.h" #include "qmdiarea.h"
#include <QLayout> #include <QLayout>
@ -723,7 +724,9 @@ void tst_QMdiSubWindow::setOpaqueResizeAndMove()
resizeSpy.clear(); resizeSpy.clear();
QCOMPARE(resizeSpy.count(), 0); 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. // Enter resize mode.
int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2; int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2;