diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-08-21 10:38:57 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2013-08-21 11:03:18 +0200 |
commit | c8ca300e491c186304d0864a9e870337e891e6f7 (patch) | |
tree | f1d991c5960b5acc0bf2a709960e871d48d91acf /src/plugins | |
parent | 31c96d34d27f8cad020238df28c10a71b2c4a34f (diff) | |
parent | 8b540f68a8404e4b9e3ac65a22c11416a91ee749 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
qmake/doc/src/qmake-manual.qdoc
src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
src/src.pro
Change-Id: I0a560826c420e46988da3776bd8f9160c365459a
Diffstat (limited to 'src/plugins')
12 files changed, 201 insertions, 97 deletions
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index f746207cc0..116c6cfa7d 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -41,7 +41,6 @@ #include "qtablegenerator.h" -#include <QtCore/QRegularExpression> #include <QtCore/QByteArray> #include <QtCore/QTextCodec> #include <QtCore/QDebug> @@ -54,7 +53,8 @@ #include <xkbcommon_workaround.h> #endif -//#define DEBUG_GENERATOR +#include <string.h> // strchr, strncmp, etc. +#include <strings.h> // strncasecmp TableGenerator::TableGenerator() : m_state(NoErrors), m_systemComposeDir(QString()) @@ -111,11 +111,9 @@ void TableGenerator::findComposeFile() // check for the system provided compose files if (!found && cleanState()) { - readLocaleMappings(); + QString table = readLocaleMappings(locale().toUpper().toUtf8()); if (cleanState()) { - - QString table = m_localeToTable.value(locale().toUpper()); if (table.isEmpty()) // no table mappings for the system's locale in the compose.dir m_state = UnsupportedLocale; @@ -174,28 +172,49 @@ QString TableGenerator::locale() const return QLatin1String(name); } -void TableGenerator::readLocaleMappings() +QString TableGenerator::readLocaleMappings(const QByteArray &locale) { QFile mappings(systemComposeDir() + QLatin1String("/compose.dir")); - if (mappings.exists()) { - mappings.open(QIODevice::ReadOnly); - QTextStream in(&mappings); - // formating of compose.dir has some inconsistencies - while (!in.atEnd()) { - QString line = in.readLine(); - if (!line.startsWith("#") && line.size() != 0 && - line.at(0).isLower()) { + QString file; + if (mappings.open(QIODevice::ReadOnly)) { + const int localeNameLength = locale.size(); + const char * const localeData = locale.constData(); - QStringList pair = line.split(QRegExp(QLatin1String("\\s+"))); - QString table = pair.at(0); - if (table.endsWith(QLatin1String(":"))) - table.remove(table.size() - 1, 1); - - m_localeToTable.insert(pair.at(1).toUpper(), table); + char l[1024]; + // formating of compose.dir has some inconsistencies + while (!mappings.atEnd()) { + int read = mappings.readLine(l, sizeof(l)); + if (read <= 0) + break; + + char *line = l; + if (*line >= 'a' && *line <= 'z') { + // file name + while (*line && *line != ':' && *line != ' ' && *line != '\t') + ++line; + if (!*line) + continue; + const char * const composeFileNameEnd = line; + *line = '\0'; + ++line; + + // locale name + while (*line && (*line == ' ' || *line == '\t')) + ++line; + const char * const lc = line; + while (*line && *line != ' ' && *line != '\t' && *line != '\n') + ++line; + *line = '\0'; + + if (localeNameLength == (line - lc) && !strncasecmp(lc, localeData, line - lc)) { + file = QString::fromUtf8(l, composeFileNameEnd - l); + break; + } } } mappings.close(); } + return file; } bool TableGenerator::processFile(QString composeFileName) @@ -215,7 +234,7 @@ TableGenerator::~TableGenerator() { } -QList<QComposeTableElement> TableGenerator::composeTable() const +QVector<QComposeTableElement> TableGenerator::composeTable() const { return m_composeTable; } @@ -225,15 +244,14 @@ void TableGenerator::parseComposeFile(QFile *composeFile) #ifdef DEBUG_GENERATOR qDebug() << "TableGenerator::parseComposeFile: " << composeFile->fileName(); #endif - QTextStream in(composeFile); - while (!in.atEnd()) { - QString line = in.readLine(); - if (line.startsWith(QLatin1String("<"))) { + char line[1024]; + while (!composeFile->atEnd()) { + composeFile->readLine(line, sizeof(line)); + if (*line == '<') parseKeySequence(line); - } else if (line.startsWith(QLatin1String("include"))) { - parseIncludeInstruction(line); - } + else if (!strncmp(line, "include", 7)) + parseIncludeInstruction(QString::fromUtf8(line)); } composeFile->close(); @@ -290,79 +308,103 @@ ushort TableGenerator::keysymToUtf8(quint32 sym) return QString::fromUtf8(chars).at(0).unicode(); } -quint32 TableGenerator::stringToKeysym(QString keysymName) +static inline int fromBase8(const char *s, const char *end) { - quint32 keysym; - QByteArray keysymArray = keysymName.toLatin1(); - const char *name = keysymArray.constData(); - - if ((keysym = xkb_keysym_from_name(name, (xkb_keysym_flags)0)) == XKB_KEY_NoSymbol) - qWarning() << QString("Qt Warning - invalid keysym: %1").arg(keysymName); + int result = 0; + while (*s && s != end) { + if (*s <= '0' && *s >= '7') + return 0; + result *= 8; + result += *s - '0'; + ++s; + } + return result; +} - return keysym; +static inline int fromBase16(const char *s, const char *end) +{ + int result = 0; + while (*s && s != end) { + result *= 16; + if (*s >= '0' && *s <= '9') + result += *s - '0'; + else if (*s >= 'a' && *s <= 'f') + result += *s - 'a' + 10; + else if (*s >= 'A' && *s <= 'F') + result += *s - 'A' + 10; + else + return 0; + ++s; + } + return result; } -void TableGenerator::parseKeySequence(QString line) +void TableGenerator::parseKeySequence(char *line) { // we are interested in the lines with the following format: // <Multi_key> <numbersign> <S> : "♬" U266c # BEAMED SIXTEENTH NOTE - int keysEnd = line.indexOf(QLatin1String(":")); - QString keys = line.left(keysEnd).trimmed(); - - // find the key sequence - QString regexp = QStringLiteral("<[^>]+>"); - QRegularExpression reg(regexp); - QRegularExpressionMatchIterator i = reg.globalMatch(keys); - QStringList keyList; - while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); - QString word = match.captured(0); - keyList << word; - } + char *keysEnd = strchr(line, ':'); + if (!keysEnd) + return; QComposeTableElement elem; - QString quote = QStringLiteral("\""); // find the composed value - strings may be direct text encoded in the locale // for which the compose file is to be used, or an escaped octal or hexadecimal // character code. Octal codes are specified as "\123" and hexadecimal codes as "\0x123a". - int composeValueIndex = line.indexOf(quote, keysEnd) + 1; - const QChar valueType(line.at(composeValueIndex)); + char *composeValue = strchr(keysEnd, '"'); + if (!composeValue) + return; + ++composeValue; + + char *composeValueEnd = strchr(composeValue, '"'); + if (!composeValueEnd) + return; - if (valueType == '\\' && line.at(composeValueIndex + 1).isDigit()) { + if (*composeValue == '\\' && composeValue[1] >= '0' && composeValue[1] <= '9') { // handle octal and hex code values - QChar detectBase(line.at(composeValueIndex + 2)); - QString codeValue = line.mid(composeValueIndex + 1, line.lastIndexOf(quote) - composeValueIndex - 1); + char detectBase = composeValue[2]; if (detectBase == 'x') { // hexadecimal character code - elem.value = keysymToUtf8(codeValue.toUInt(0, 16)); + elem.value = keysymToUtf8(fromBase16(composeValue + 3, composeValueEnd)); } else { // octal character code - QString hexStr = QString::number(codeValue.toUInt(0, 8), 16); - elem.value = keysymToUtf8(hexStr.toUInt(0, 16)); + elem.value = keysymToUtf8(fromBase8(composeValue + 1, composeValueEnd)); } } else { // handle direct text encoded in the locale - elem.value = valueType.unicode(); + if (*composeValue == '\\') + ++composeValue; + elem.value = QString::fromUtf8(composeValue).at(0).unicode(); + ++composeValue; } +#ifdef DEBUG_GENERATOR // find the comment - int commnetIndex = line.lastIndexOf(quote) + 1; - elem.comment = line.mid(commnetIndex).trimmed(); - - // Convert to X11 keysym - int count = keyList.length(); - for (int i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) { - if (i < count) { - QString keysym = keyList.at(i); - keysym.remove(keysym.length() - 1, 1); - keysym.remove(0, 1); + elem.comment = QString::fromUtf8(composeValueEnd + 1).trimmed(); +#endif - if (keysym == QLatin1String("dead_inverted_breve")) - keysym = QStringLiteral("dead_invertedbreve"); - else if (keysym == QLatin1String("dead_double_grave")) - keysym = QStringLiteral("dead_doublegrave"); + // find the key sequence and convert to X11 keysym + char *k = line; + const char *kend = keysEnd; - elem.keys[i] = stringToKeysym(keysym); + for (int i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) { + // find the next pair of angle brackets and get the contents within + while (k < kend && *k != '<') + ++k; + char *sym = ++k; + while (k < kend && *k != '>') + ++k; + *k = '\0'; + if (k < kend) { + elem.keys[i] = xkb_keysym_from_name(sym, (xkb_keysym_flags)0); + if (elem.keys[i] == XKB_KEY_NoSymbol) { + if (!strcmp(sym, "dead_inverted_breve")) + elem.keys[i] = XKB_KEY_dead_invertedbreve; + else if (!strcmp(sym, "dead_double_grave")) + elem.keys[i] = XKB_KEY_dead_doublegrave; + else + qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym); + } } else { elem.keys[i] = 0; } @@ -372,6 +414,7 @@ void TableGenerator::parseKeySequence(QString line) void TableGenerator::printComposeTable() const { +#ifdef DEBUG_GENERATOR if (composeTable().isEmpty()) return; @@ -393,8 +436,8 @@ void TableGenerator::printComposeTable() const .arg(comma) .arg(elem.comment)); } - qDebug() << "output: \n" << output; +#endif } void TableGenerator::orderComposeTable() diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h index cc1db20432..aa65b7b895 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h @@ -42,19 +42,29 @@ #ifndef QTABLEGENERATOR_H #define QTABLEGENERATOR_H -#include <QtCore/QList> +#include <QtCore/QVector> #include <QtCore/QFile> #include <QtCore/QMap> #include <QtCore/QString> #define QT_KEYSEQUENCE_MAX_LEN 6 +//#define DEBUG_GENERATOR + struct QComposeTableElement { uint keys[QT_KEYSEQUENCE_MAX_LEN]; uint value; +#ifdef DEBUG_GENERATOR QString comment; +#endif }; +#ifndef DEBUG_GENERATOR +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(QComposeTableElement, Q_PRIMITIVE_TYPE); +QT_END_NAMESPACE +#endif + class Compare { public: @@ -97,12 +107,12 @@ public: void printComposeTable() const; void orderComposeTable(); - QList<QComposeTableElement> composeTable() const; + QVector<QComposeTableElement> composeTable() const; TableState tableState() const { return m_state; } protected: bool processFile(QString composeFileName); - void parseKeySequence(QString line); + void parseKeySequence(char *line); void parseIncludeInstruction(QString line); void findComposeFile(); @@ -110,16 +120,14 @@ protected: QString systemComposeDir(); ushort keysymToUtf8(quint32 sym); - quint32 stringToKeysym(QString keysymName); - void readLocaleMappings(); + QString readLocaleMappings(const QByteArray &locale); void initPossibleLocations(); bool cleanState() const { return ((m_state & NoErrors) == NoErrors); } QString locale() const; private: - QList<QComposeTableElement> m_composeTable; - QMap<QString, QString> m_localeToTable; + QVector<QComposeTableElement> m_composeTable; TableState m_state; QString m_systemComposeDir; QList<QString> m_possibleLocations; diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index 433c9eec37..611b9fdd9b 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -169,11 +169,11 @@ static bool isDuplicate(const QComposeTableElement &lhs, const QComposeTableElem bool QComposeInputContext::checkComposeTable() { - QList<QComposeTableElement>::iterator it = - qLowerBound(m_composeTable.begin(), m_composeTable.end(), m_composeBuffer, Compare()); + QVector<QComposeTableElement>::const_iterator it = + qLowerBound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare()); // prevent dereferencing an 'end' iterator, which would result in a crash - if (it == m_composeTable.end()) + if (it == m_composeTable.constEnd()) it -= 1; QComposeTableElement elem = *it; diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h index 1ced2f8ded..def63486a7 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h @@ -75,7 +75,7 @@ protected: private: QObject *m_focusObject; - QList<QComposeTableElement> m_composeTable; + QVector<QComposeTableElement> m_composeTable; uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN + 1]; TableGenerator::TableState m_tableState; }; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 5649f3ad73..e135f36e78 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -231,8 +231,7 @@ NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface) NSMutableArray *kids = [NSMutableArray arrayWithCapacity:numKids]; for (int i = 0; i < numKids; ++i) { QAccessibleInterface *child = interface->child(i); - Q_ASSERT(child); - if (child->state().invalid || child->state().invisible) + if (!child || !child->isValid() || child->state().invalid || child->state().invisible) continue; QAccessible::Id childId = QAccessible::uniqueId(child); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index fcebb7e0dc..20f767e240 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -489,6 +489,9 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) [m_nsWindow setStyleMask:styleMask]; [m_nsWindow setLevel:level]; setWindowShadow(flags); + if (!(styleMask & NSBorderlessWindowMask)) { + setWindowTitle(window()->title()); + } } m_windowFlags = flags; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3063ce452e..e529e445ad 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1034,7 +1034,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) { NSEventPhase phase = [theEvent phase]; - if (phase == NSEventPhaseBegan) { + if (phase == NSEventPhaseBegan || phase == NSEventPhaseNone) { currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; } @@ -1056,7 +1056,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph); - if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) { + if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled || phase == NSEventPhaseNone) { currentWheelModifiers = Qt::NoModifier; } } else @@ -1142,7 +1142,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) if (m_sendKeyEvent && m_composingText.isEmpty()) QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers, - nativeScanCode, nativeVirtualKey, nativeModifiers, text); + nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]); m_sendKeyEvent = false; } diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index dcd3db2d47..64bf1d71ca 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -89,6 +89,7 @@ enum WindowsEventType // Simplify event types CursorEvent = MouseEventFlag + 3, TouchEvent = TouchEventFlag + 1, NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1, + NonClientHitTest = NonClientEventFlag + 2, KeyEvent = KeyEventFlag + 1, KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1, InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1, @@ -143,6 +144,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::ResizeEvent; case WM_NCCALCSIZE: return QtWindows::CalculateSize; +#ifndef Q_OS_WINCE + case WM_NCHITTEST: + return QtWindows::NonClientHitTest; +#endif // !Q_OS_WINCE case WM_GETMINMAXINFO: return QtWindows::QuerySizeHints; case WM_KEYDOWN: // keyboard event diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index de0a583e58..132b3684e9 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -839,7 +839,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true;// maybe available on some SDKs revisit WM_NCCALCSIZE case QtWindows::CalculateSize: return QWindowsGeometryHint::handleCalculateSize(platformWindow->customMargins(), msg, result); -#endif + case QtWindows::NonClientHitTest: + return platformWindow->handleNonClientHitTest(QPoint(msg.pt.x, msg.pt.y), result); +#endif // !Q_OS_WINCE case QtWindows::ExposeEvent: return platformWindow->handleWmPaint(hwnd, message, wParam, lParam); case QtWindows::NonClientMouseEvent: diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index e7e964a128..8ec10294a2 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1796,6 +1796,47 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const if (QWindowsContext::verboseWindows) qDebug() << __FUNCTION__ << window() << *mmi; } + +bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *result) const +{ + // QTBUG-32663, suppress resize cursor for fixed size windows. + const QWindow *w = window(); + if (!w->isTopLevel() // Task 105852, minimized windows need to respond to user input. + || (m_windowState != Qt::WindowNoState && m_windowState != Qt::WindowActive) + || (m_data.flags & Qt::FramelessWindowHint)) { + return false; + } + const QSize minimumSize = w->minimumSize(); + if (minimumSize.isEmpty()) + return false; + const QSize maximumSize = w->maximumSize(); + const bool fixedWidth = minimumSize.width() == maximumSize.width(); + const bool fixedHeight = minimumSize.height() == maximumSize.height(); + if (!fixedWidth && !fixedHeight) + return false; + const QPoint localPos = w->mapFromGlobal(globalPos); + const QSize size = w->size(); + if (fixedHeight) { + if (localPos.y() >= size.height()) { + *result = HTBORDER; // Unspecified border, no resize cursor. + return true; + } + if (localPos.y() < 0) { + const QMargins margins = frameMargins(); + const int topResizeBarPos = margins.left() - margins.top(); + if (localPos.y() < topResizeBarPos) { + *result = HTCAPTION; // Extend caption over top resize bar, let's user move the window. + return true; + } + } + } + if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) { + *result = HTBORDER; // Unspecified border, no resize cursor. + return true; + } + return false; +} + #endif // !Q_OS_WINCE #ifndef QT_NO_CURSOR diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 996542f92a..f7d142fc36 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -234,7 +234,8 @@ public: void releaseDC(); #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO void getSizeHints(MINMAXINFO *mmi) const; -#endif + bool handleNonClientHitTest(const QPoint &globalPos, LRESULT *result) const; +#endif // !Q_OS_WINCE #ifndef QT_NO_CURSOR QWindowsWindowCursor cursor() const { return m_cursor; } diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index ee1fe44530..b144d953a7 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -419,8 +419,6 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) touchPoint.state = Qt::TouchPointMoved; dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); } - else - touchPoint.state = Qt::TouchPointStationary; break; case XI_TouchEnd: touchPoint.state = Qt::TouchPointReleased; @@ -442,9 +440,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) " area " << touchPoint.area << " pressure " << touchPoint.pressure; #endif QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values()); - // If a touchpoint was released, we can forget it, because the ID won't be reused. if (touchPoint.state == Qt::TouchPointReleased) + // If a touchpoint was released, we can forget it, because the ID won't be reused. m_touchPoints.remove(touchPoint.id); + else + // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent + // with this touch point if the next XI2 event is about a different touch point. + touchPoint.state = Qt::TouchPointStationary; } } #endif // XCB_USE_XINPUT22 |