diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-11 08:24:34 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-11 08:25:04 +0100 |
commit | d456f87ece0323982b7601047712545ab95426ad (patch) | |
tree | 46b90468b01144615f280620d73763fc189d25ac /src/plugins | |
parent | cc2938b5b6aa07210b04bd48ad8a2830701a06e5 (diff) | |
parent | 4fc070a4192d5b914b6f814a8dcab3f552d9abac (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts:
src/corelib/io/qfilesystemwatcher_win.cpp
src/corelib/plugin/plugin.pri
src/plugins/platforms/cocoa/qcocoaaccessibility.mm
tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
Change-Id: Id6824631252609a75eff8b68792e4d10095c8fc1
Diffstat (limited to 'src/plugins')
30 files changed, 313 insertions, 602 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 49cf9968cc..7028b4d9ec 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -41,6 +41,8 @@ #include <QtGui/qaccessible.h> #include <private/qcore_mac_p.h> +#include <Carbon/Carbon.h> + QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY @@ -201,6 +203,8 @@ NSString *macSubrole(QAccessibleInterface *interface) QAccessible::State s = interface->state(); if (s.searchEdit) return NSAccessibilitySearchFieldSubrole; + if (s.passwordEdit) + return NSAccessibilitySecureTextFieldSubrole; return nil; } @@ -359,18 +363,23 @@ id getValueAttribute(QAccessibleInterface *interface) } if (qtrole == QAccessible::EditableText) { if (QAccessibleTextInterface *textInterface = interface->textInterface()) { - // VoiceOver will read out the entire text string at once when returning - // text as a value. For large text edits the size of the returned string - // needs to be limited and text range attributes need to be used instead. - // NSTextEdit returns the first sentence as the value, Do the same here: + int begin = 0; int end = textInterface->characterCount(); - // ### call to textAfterOffset hangs. Booo! - //if (textInterface->characterCount() > 0) - // textInterface->textAfterOffset(0, QAccessible2::SentenceBoundary, &begin, &end); - - QString text = textInterface->text(begin, end); - //qDebug() << "text" << begin << end << text; + QString text; + if (interface->state().passwordEdit) { + // return round password replacement chars + text = QString(end, QChar(kBulletUnicode)); + } else { + // VoiceOver will read out the entire text string at once when returning + // text as a value. For large text edits the size of the returned string + // needs to be limited and text range attributes need to be used instead. + // NSTextEdit returns the first sentence as the value, Do the same here: + // ### call to textAfterOffset hangs. Booo! + //if (textInterface->characterCount() > 0) + // textInterface->textAfterOffset(0, QAccessible2::SentenceBoundary, &begin, &end); + text = textInterface->text(begin, end); + } return QCFString::toNSString(text); } } diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp index 5cea082873..29b01391e2 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp @@ -69,6 +69,10 @@ QWindowsDirect2DPaintDevice::QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap { } +QWindowsDirect2DPaintDevice::~QWindowsDirect2DPaintDevice() +{ +} + QPaintEngine *QWindowsDirect2DPaintDevice::paintEngine() const { Q_D(const QWindowsDirect2DPaintDevice); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h index 27be326150..f434ef993c 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h @@ -56,6 +56,8 @@ class QWindowsDirect2DPaintDevice : public QPaintDevice public: QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags, QWindowsDirect2DPaintEngine::Flags paintFlags = QWindowsDirect2DPaintEngine::NoFlag); + ~QWindowsDirect2DPaintDevice(); + QPaintEngine *paintEngine() const Q_DECL_OVERRIDE; int devType() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 79413622a8..201d9d7443 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -307,8 +307,13 @@ void QEglFSKmsEglDeviceIntegration::waitForVSync(QPlatformSurface *) const if (currentMode) drmModeFreeCrtc(currentMode); if (alreadySet) { - qCDebug(qLcEglfsKmsDebug, "Mode already set"); - return; + // Maybe detecting the DPMS mode could help here, but there are no properties + // exposed on the connector apparently. So rely on an env var for now. + static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); + if (!alwaysDoSet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set"); + return; + } } qCDebug(qLcEglfsKmsDebug, "Setting mode"); diff --git a/src/plugins/platforms/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp index 060d5a40b6..ac3683f4d5 100644 --- a/src/plugins/platforms/windows/accessible/comutils.cpp +++ b/src/plugins/platforms/windows/accessible/comutils.cpp @@ -278,348 +278,6 @@ bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeN } } break; -#if 0 // not a value with min/max semantics - case QVariant::Font: - if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) { - if (*arg.ppdispVal) - (*arg.ppdispVal)->Release(); - *arg.ppdispVal = QFontToIFont(qvariant_cast<QFont>(qvar)); - } else { - arg.vt = VT_DISPATCH; - arg.pdispVal = QFontToIFont(qvariant_cast<QFont>(qvar)); - if (out) { - arg.ppdispVal = new IDispatch*(arg.pdispVal); - arg.vt |= VT_BYREF; - } - } - break; - case QVariant::Pixmap: - if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) { - if (*arg.ppdispVal) - (*arg.ppdispVal)->Release(); - *arg.ppdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar)); - } else { - arg.vt = VT_DISPATCH; - arg.pdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar)); - if (out) { - arg.ppdispVal = new IDispatch*(arg.pdispVal); - arg.vt |= VT_BYREF; - } - } - break; - case QVariant::Cursor: - { -#ifndef QT_NO_CURSOR - int shape = qvariant_cast<QCursor>(qvar).shape(); - if (out && (arg.vt & VT_BYREF)) { - switch (arg.vt & ~VT_BYREF) { - case VT_I4: - *arg.plVal = shape; - break; - case VT_I2: - *arg.piVal = shape; - break; - case VT_UI4: - *arg.pulVal = shape; - break; - case VT_UI2: - *arg.puiVal = shape; - break; - case VT_INT: - *arg.pintVal = shape; - break; - case VT_UINT: - *arg.puintVal = shape; - break; - } - } else { - arg.vt = VT_I4; - arg.lVal = shape; - if (out) { - arg.plVal = new long(arg.lVal); - arg.vt |= VT_BYREF; - } - } -#endif - } - break; - - case QVariant::List: - { - const QList<QVariant> list = qvar.toList(); - const int count = list.count(); - VARTYPE vt = VT_VARIANT; - QVariant::Type listType = QVariant::LastType; // == QVariant - if (!typeName.isEmpty() && typeName.startsWith("QList<")) { - const QByteArray listTypeName = typeName.mid(6, typeName.length() - 7); // QList<int> -> int - listType = QVariant::nameToType(listTypeName); - } - - VARIANT variant; - void *pElement = &variant; - switch (listType) { - case QVariant::Int: - vt = VT_I4; - pElement = &variant.lVal; - break; - case QVariant::Double: - vt = VT_R8; - pElement = &variant.dblVal; - break; - case QVariant::DateTime: - vt = VT_DATE; - pElement = &variant.date; - break; - case QVariant::Bool: - vt = VT_BOOL; - pElement = &variant.boolVal; - break; - case QVariant::LongLong: -#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400 - vt = VT_I8; - pElement = &variant.llVal; -#else - vt = VT_CY; - pElement = &variant.cyVal; -#endif - break; - default: - break; - } - SAFEARRAY *array = 0; - bool is2D = false; - // If the first element in the array is a list the whole list is - // treated as a 2D array. The column count is taken from the 1st element. - if (count) { - QVariantList col = list.at(0).toList(); - int maxColumns = col.count(); - if (maxColumns) { - is2D = true; - SAFEARRAYBOUND rgsabound[2] = { {0} }; - rgsabound[0].cElements = count; - rgsabound[1].cElements = maxColumns; - array = SafeArrayCreate(VT_VARIANT, 2, rgsabound); - LONG rgIndices[2]; - for (LONG i = 0; i < count; ++i) { - rgIndices[0] = i; - QVariantList columns = list.at(i).toList(); - int columnCount = qMin(maxColumns, columns.count()); - for (LONG j = 0; j < columnCount; ++j) { - QVariant elem = columns.at(j); - VariantInit(&variant); - QVariant2VARIANT(elem, variant, elem.typeName()); - rgIndices[1] = j; - SafeArrayPutElement(array, rgIndices, pElement); - clearVARIANT(&variant); - } - } - - } - } - if (!is2D) { - array = SafeArrayCreateVector(vt, 0, count); - for (LONG index = 0; index < count; ++index) { - QVariant elem = list.at(index); - if (listType != QVariant::LastType) - elem.convert(listType); - VariantInit(&variant); - QVariant2VARIANT(elem, variant, elem.typeName()); - SafeArrayPutElement(array, &index, pElement); - clearVARIANT(&variant); - } - } - if (out && arg.vt == (VT_ARRAY|vt|VT_BYREF)) { - if (*arg.pparray) - SafeArrayDestroy(*arg.pparray); - *arg.pparray = array; - } else { - arg.vt = VT_ARRAY|vt; - arg.parray = array; - if (out) { - arg.pparray = new SAFEARRAY*(arg.parray); - arg.vt |= VT_BYREF; - } - } - } - break; - - case QVariant::StringList: - { - const QStringList list = qvar.toStringList(); - const int count = list.count(); - SAFEARRAY *array = SafeArrayCreateVector(VT_BSTR, 0, count); - for (LONG index = 0; index < count; ++index) { - QString elem = list.at(index); - BSTR bstr = QStringToBSTR(elem); - SafeArrayPutElement(array, &index, bstr); - SysFreeString(bstr); - } - - if (out && arg.vt == (VT_ARRAY|VT_BSTR|VT_BYREF)) { - if (*arg.pparray) - SafeArrayDestroy(*arg.pparray); - *arg.pparray = array; - } else { - arg.vt = VT_ARRAY|VT_BSTR; - arg.parray = array; - if (out) { - arg.pparray = new SAFEARRAY*(arg.parray); - arg.vt |= VT_BYREF; - } - } - } - break; - - case QVariant::ByteArray: - { - const QByteArray bytes = qvar.toByteArray(); - const uint count = bytes.count(); - SAFEARRAY *array = SafeArrayCreateVector(VT_UI1, 0, count); - if (count) { - const char *data = bytes.constData(); - char *dest; - SafeArrayAccessData(array, (void **)&dest); - memcpy(dest, data, count); - SafeArrayUnaccessData(array); - } - - if (out && arg.vt == (VT_ARRAY|VT_UI1|VT_BYREF)) { - if (*arg.pparray) - SafeArrayDestroy(*arg.pparray); - *arg.pparray = array; - } else { - arg.vt = VT_ARRAY|VT_UI1; - arg.parray = array; - if (out) { - arg.pparray = new SAFEARRAY*(arg.parray); - arg.vt |= VT_BYREF; - } - } - } - break; - -#ifdef QAX_SERVER - case QVariant::Rect: - case QVariant::Size: - case QVariant::Point: - { - typedef HRESULT(WINAPI* PGetRecordInfoFromTypeInfo)(ITypeInfo *, IRecordInfo **); - static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0; - static bool resolved = false; - if (!resolved) { - QSystemLibrary oleaut32(QLatin1String("oleaut32")); - pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)oleaut32.resolve("GetRecordInfoFromTypeInfo"); - resolved = true; - } - if (!pGetRecordInfoFromTypeInfo) - break; - - ITypeInfo *typeInfo = 0; - IRecordInfo *recordInfo = 0; - CLSID clsid = qvar.type() == QVariant::Rect ? CLSID_QRect - :qvar.type() == QVariant::Size ? CLSID_QSize - :CLSID_QPoint; - qAxTypeLibrary->GetTypeInfoOfGuid(clsid, &typeInfo); - if (!typeInfo) - break; - pGetRecordInfoFromTypeInfo(typeInfo, &recordInfo); - typeInfo->Release(); - if (!recordInfo) - break; - - void *record = 0; - switch (qvar.type()) { - case QVariant::Rect: - { - QRect qrect(qvar.toRect()); - recordInfo->RecordCreateCopy(&qrect, &record); - } - break; - case QVariant::Size: - { - QSize qsize(qvar.toSize()); - recordInfo->RecordCreateCopy(&qsize, &record); - } - break; - case QVariant::Point: - { - QPoint qpoint(qvar.toPoint()); - recordInfo->RecordCreateCopy(&qpoint, &record); - } - break; - } - - arg.vt = VT_RECORD; - arg.pRecInfo = recordInfo, - arg.pvRecord = record; - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for records"); - return false; - } - } - break; -#endif // QAX_SERVER - case QVariant::UserType: - { - QByteArray subType = qvar.typeName(); -#ifdef QAX_SERVER - if (subType.endsWith('*')) - subType.truncate(subType.length() - 1); -#endif - if (!qstrcmp(qvar.typeName(), "IDispatch*")) { - arg.vt = VT_DISPATCH; - arg.pdispVal = *(IDispatch**)qvar.data(); - if (arg.pdispVal) - arg.pdispVal->AddRef(); - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for IDispatch"); - return false; - } - } else if (!qstrcmp(qvar.typeName(), "IDispatch**")) { - arg.vt = VT_DISPATCH; - arg.ppdispVal = *(IDispatch***)qvar.data(); - if (out) - arg.vt |= VT_BYREF; - } else if (!qstrcmp(qvar.typeName(), "IUnknown*")) { - arg.vt = VT_UNKNOWN; - arg.punkVal = *(IUnknown**)qvar.data(); - if (arg.punkVal) - arg.punkVal->AddRef(); - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for IUnknown"); - return false; - } -#ifdef QAX_SERVER - } else if (qAxFactory()->metaObject(QString::fromLatin1(subType.constData()))) { - arg.vt = VT_DISPATCH; - void *user = *(void**)qvar.constData(); -// qVariantGet(qvar, user, qvar.typeName()); - if (!user) { - arg.pdispVal = 0; - } else { - qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal); - } - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for subtype"); - return false; - } -#else - } else if (QMetaType::type(subType)) { - QAxObject *object = *(QAxObject**)qvar.constData(); -// qVariantGet(qvar, object, subType); - arg.vt = VT_DISPATCH; - object->queryInterface(IID_IDispatch, (void**)&arg.pdispVal); - if (out) { - qWarning("QVariant2VARIANT: out-parameter not supported for subtype"); - return false; - } -#endif - } else { - return false; - } - } - break; -#endif case QVariant::Invalid: // default-parameters not set if (out && arg.vt == (VT_ERROR|VT_BYREF)) { diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 849a97c1ba..d81044cdda 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -1705,12 +1705,12 @@ QByteArray QWindowsIA2Accessible::IIDToString(REFIID id) } // Q_STATIC_ASSERT(IA2_ROLE_CANVAS == QAccessible::Canvas); // ### Qt 6: make them the same -Q_STATIC_ASSERT(IA2_ROLE_COLOR_CHOOSER == QAccessible::ColorChooser); -Q_STATIC_ASSERT(IA2_ROLE_FOOTER == QAccessible::Footer); -Q_STATIC_ASSERT(IA2_ROLE_FORM == QAccessible::Form); -Q_STATIC_ASSERT(IA2_ROLE_HEADING == QAccessible::Heading); -Q_STATIC_ASSERT(IA2_ROLE_NOTE == QAccessible::Note); -Q_STATIC_ASSERT(IA2_ROLE_COMPLEMENTARY_CONTENT == QAccessible::ComplementaryContent); +Q_STATIC_ASSERT(IA2_ROLE_COLOR_CHOOSER == static_cast<IA2Role>(QAccessible::ColorChooser)); +Q_STATIC_ASSERT(IA2_ROLE_FOOTER == static_cast<IA2Role>(QAccessible::Footer)); +Q_STATIC_ASSERT(IA2_ROLE_FORM == static_cast<IA2Role>(QAccessible::Form)); +Q_STATIC_ASSERT(IA2_ROLE_HEADING == static_cast<IA2Role>(QAccessible::Heading)); +Q_STATIC_ASSERT(IA2_ROLE_NOTE == static_cast<IA2Role>(QAccessible::Note)); +Q_STATIC_ASSERT(IA2_ROLE_COMPLEMENTARY_CONTENT == static_cast<IA2Role>(QAccessible::ComplementaryContent)); QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 13eee8e0fa..f91e57ae2f 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -225,24 +225,6 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) #endif // defined(Q_OS_WINCE) } -/* -void QWindowsAccessibility::setRootObject(QObject *o) -{ - -} - -void QWindowsAccessibility::initialize() -{ - -} - -void QWindowsAccessibility::cleanup() -{ - -} - -*/ - bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) { #if !defined(Q_OS_WINCE) @@ -251,12 +233,10 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W } else if ((DWORD)lParam == DWORD(OBJID_CLIENT)) { // Start handling accessibility internally QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); -#if 1 // Ignoring all requests while starting up // ### Maybe QPA takes care of this??? if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) return false; -#endif typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN); static PtrLresultFromObject ptrLresultFromObject = 0; diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h index 157b4cac8e..e035e3924a 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h @@ -53,12 +53,7 @@ class QWindowsAccessibility : public QPlatformAccessibility public: QWindowsAccessibility(); static bool handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult); - virtual void notifyAccessibilityUpdate(QAccessibleEvent *event); - /* - virtual void setRootObject(QObject *o); - virtual void initialize(); - virtual void cleanup(); - */ + void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE; static IAccessible *wrap(QAccessibleInterface *acc); static QWindow *windowHelper(const QAccessibleInterface *iface); }; diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 9bd23577cc..95e595b88e 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -57,9 +57,6 @@ QT_BEGIN_NAMESPACE -static const char formatTextPlainC[] = "text/plain"; -static const char formatTextHtmlC[] = "text/html"; - /*! \class QWindowsClipboard \brief Clipboard implementation. diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 1f66de23ca..8501ec6731 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -95,20 +95,6 @@ Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility") int QWindowsContext::verbose = 0; -// Get verbosity of components from "foo:2,bar:3" -static inline int componentVerbose(const char *v, const char *keyWord) -{ - if (const char *k = strstr(v, keyWord)) { - k += qstrlen(keyWord); - if (*k == ':') { - ++k; - if (isdigit(*k)) - return *k - '0'; - } - } - return 0; -} - #if !defined(LANG_SYRIAC) # define LANG_SYRIAC 0x5a #endif diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 166328cf5e..5c2610a3fe 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -252,9 +252,10 @@ static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR) return primaryScreenCursorSize; } +#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG) + static inline QSize standardCursorSize() { return QSize(32, 32); } -#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG) // Create pixmap cursors from data and scale the image if the cursor size is // higher than the standard 32. Note that bitmap cursors as produced by // createBitmapCursor() only work for standard sizes (32,48,64...), which does diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 594208ab17..72d9d5a71b 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -743,7 +743,7 @@ inline QUrl QWindowsFileDialogSharedData::directory() const inline void QWindowsFileDialogSharedData::setDirectory(const QUrl &d) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->directory = d; } @@ -757,7 +757,7 @@ inline QString QWindowsFileDialogSharedData::selectedNameFilter() const inline void QWindowsFileDialogSharedData::setSelectedNameFilter(const QString &f) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->selectedNameFilter = f; } @@ -777,13 +777,13 @@ inline QString QWindowsFileDialogSharedData::selectedFile() const inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &urls) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->selectedFiles = urls; } inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o) { - QMutexLocker (&m_data->mutex); + QMutexLocker locker(&m_data->mutex); m_data->directory = o->initialDirectory(); m_data->selectedFiles = o->initiallySelectedFiles(); m_data->selectedNameFilter = o->initiallySelectedNameFilter(); @@ -1590,11 +1590,6 @@ QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialogOp return result; } -static inline bool isQQuickWindow(const QWindow *w = 0) -{ - return w && w->inherits("QQuickWindow"); -} - /*! \class QWindowsFileDialogHelper \brief Helper for native Windows file dialogs @@ -1610,8 +1605,8 @@ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDi { public: QWindowsFileDialogHelper() {} - virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; } - virtual bool defaultNameFilterDisables() const + virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; } + virtual bool defaultNameFilterDisables() const Q_DECL_OVERRIDE { return false; } virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; virtual QUrl directory() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index 23ab8d9991..b643d9a920 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -70,9 +70,9 @@ public: ~QWindowsDialogHelperBase() { cleanupThread(); } void exec() Q_DECL_OVERRIDE; - virtual bool show(Qt::WindowFlags windowFlags, + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, - QWindow *parent); + QWindow *parent) Q_DECL_OVERRIDE; void hide() Q_DECL_OVERRIDE; virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; } @@ -81,7 +81,7 @@ protected: QWindowsDialogHelperBase(); QWindowsNativeDialogBase *nativeDialog() const; inline bool hasNativeDialog() const { return m_nativeDialog; } - void timerEvent(QTimerEvent *); + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE; private: virtual QWindowsNativeDialogBase *createNativeDialog() = 0; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index eee264c5dc..da28b5b19b 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -348,8 +348,8 @@ bool QWindowsLibGLESv2::init() return glBindTexture && glCreateShader && glClearDepthf; } -QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display, int version) - : m_display(display), m_version(version) +QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display) + : m_display(display) { } @@ -416,7 +416,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: } qCDebug(lcQpaGl) << __FUNCTION__ << "Created EGL display" << display << 'v' <<major << '.' << minor; - return new QWindowsEGLStaticContext(display, (major << 8) | minor); + return new QWindowsEGLStaticContext(display); } QWindowsEGLStaticContext::~QWindowsEGLStaticContext() diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 944bdff9b6..ccc2cdcad1 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -263,9 +263,9 @@ public: EGLDisplay display() const { return m_display; } - QWindowsOpenGLContext *createContext(QOpenGLContext *context); - void *moduleHandle() const { return libGLESv2.moduleHandle(); } - QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; } + QWindowsOpenGLContext *createContext(QOpenGLContext *context) Q_DECL_OVERRIDE; + void *moduleHandle() const Q_DECL_OVERRIDE { return libGLESv2.moduleHandle(); } + QOpenGLContext::OpenGLModuleType moduleType() const Q_DECL_OVERRIDE { return QOpenGLContext::LibGLES; } void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE; void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE; @@ -276,10 +276,9 @@ public: static QWindowsLibGLESv2 libGLESv2; private: - QWindowsEGLStaticContext(EGLDisplay display, int version); + explicit QWindowsEGLStaticContext(EGLDisplay display); const EGLDisplay m_display; - const int m_version; //! majorVersion<<8 + minorVersion }; class QWindowsEGLContext : public QWindowsOpenGLContext diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index be9cc8bf77..8b61379c42 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -458,6 +458,8 @@ static bool addFontToDatabase(const QString &faceName, const FontKey *key = findFontKey(faceName, &index); if (!key) { key = findFontKey(fullName, &index); + if (!key && !registerAlias && englishName.isEmpty() && localizedName(faceName)) + englishName = getEnglishName(faceName); if (!key && !englishName.isEmpty()) key = findFontKey(englishName, &index); if (!key) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ed7fa441b2..1b88f8bbe4 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -110,17 +110,6 @@ static void resolveGetCharWidthI() ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI"); } -static inline quint32 getUInt(unsigned char *p) -{ - quint32 val; - val = *p++ << 24; - val |= *p++ << 16; - val |= *p++ << 8; - val |= *p; - - return val; -} - static inline quint16 getUShort(unsigned char *p) { quint16 val; @@ -272,7 +261,6 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name, m_logfont(lf), ttf(0), hasOutline(0), - lw(0), cmap(0), cmapSize(0), lbearing(SHRT_MIN), @@ -1168,7 +1156,9 @@ glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, c QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) { HFONT font = hfont; - if (m_fontEngineData->clearTypeEnabled) { + + bool clearTypeTemporarilyDisabled = (m_fontEngineData->clearTypeEnabled && m_logfont.lfQuality != NONANTIALIASED_QUALITY); + if (clearTypeTemporarilyDisabled) { LOGFONT lf = m_logfont; lf.lfQuality = ANTIALIASED_QUALITY; font = CreateFontIndirect(&lf); @@ -1207,7 +1197,7 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo // Cleanup... delete mask; - if (m_fontEngineData->clearTypeEnabled) { + if (clearTypeTemporarilyDisabled) { DeleteObject(font); } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index 75bff00326..7d85b7ef24 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -150,7 +150,6 @@ private: uint hasUnreliableOutline : 1; uint cffTable : 1; TEXTMETRIC tm; - int lw; const unsigned char *cmap; int cmapSize; QByteArray cmapTable; diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 4b002799b6..6fc49c1384 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -620,10 +620,6 @@ static inline int asciiToKeycode(char a, int state) return a & 0xff; } -static inline bool isModifierKey(int code) -{ - return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock); -} // Key translation -----------------------------------------------------------------------[ end ]--- diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cd5deaf8c0..84428c2b1f 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -83,22 +83,6 @@ static inline QDpi monitorDPI(HMONITOR hMonitor) #endif // !Q_OS_WINCE -static inline QSizeF deviceSizeMM(const QSize &pixels, const QDpi &dpi) -{ - const qreal inchToMM = 25.4; - const qreal h = qreal(pixels.width()) / qreal(dpi.first) * inchToMM; - const qreal v = qreal(pixels.height()) / qreal(dpi.second) * inchToMM; - return QSizeF(h, v); -} - -static inline QDpi deviceDPI(const QSize &pixels, const QSizeF &physicalSizeMM) -{ - const qreal inchToMM = 25.4; - const qreal h = qreal(pixels.width()) / (qreal(physicalSizeMM.width()) / inchToMM); - const qreal v = qreal(pixels.height()) / (qreal(physicalSizeMM.height()) / inchToMM); - return QDpi(h, v); -} - typedef QList<QWindowsScreenData> WindowsScreenDataList; static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 439f220046..5c283a3113 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -84,11 +84,6 @@ QT_BEGIN_NAMESPACE -static inline COLORREF qColorToCOLORREF(const QColor &color) -{ - return RGB(color.red(), color.green(), color.blue()); -} - static inline QColor COLORREFToQColor(COLORREF cr) { return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr)); @@ -105,30 +100,6 @@ static inline QTextStream& operator<<(QTextStream &str, const QColor &c) return str; } -static inline void paletteRoleToString(const QPalette &palette, - const QPalette::ColorRole role, - QTextStream &str) -{ - str << "Role: "; - str.setFieldWidth(2); - str.setPadChar(QLatin1Char('0')); - str << role; - str.setFieldWidth(0); - str << " Active: " << palette.color(QPalette::Active, role) - << " Disabled: " << palette.color(QPalette::Disabled, role) - << " Inactive: " << palette.color(QPalette::Inactive, role) - << '\n'; -} - -static inline QString paletteToString(const QPalette &palette) -{ - QString result; - QTextStream str(&result); - for (int r = 0; r < QPalette::NColorRoles; ++r) - paletteRoleToString(palette, static_cast<QPalette::ColorRole>(r), str); - return result; -} - static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue) { BOOL result; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index e83d44bbfe..22a2922235 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -254,13 +254,6 @@ static QWindow::Visibility windowVisibility_sys(HWND hwnd) return QWindow::Windowed; } -static inline QSize clientSize(HWND hwnd) -{ - RECT rect = { 0, 0, 0, 0 }; - GetClientRect(hwnd, &rect); // Always returns point 0,0, thus unusable for geometry. - return qSizeOfRect(rect); -} - static inline bool windowIsOpenGL(const QWindow *w) { switch (w->surfaceType()) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4d29cdc316..998f4884aa 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -619,8 +619,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra initializeScreens(); initializeXRender(); - m_xi2Enabled = false; #if defined(XCB_USE_XINPUT2) + m_xi2Enabled = false; initializeXInput2(); #endif initializeXShape(); @@ -1142,8 +1142,16 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) handleClientMessageEvent((xcb_client_message_event_t *)event); break; case XCB_ENTER_NOTIFY: +#ifdef XCB_USE_XINPUT22 + if (isAtLeastXI22() && xi2MouseEvents()) + break; +#endif HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); case XCB_LEAVE_NOTIFY: +#ifdef XCB_USE_XINPUT22 + if (isAtLeastXI22() && xi2MouseEvents()) + break; +#endif m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent); case XCB_FOCUS_IN: @@ -1930,6 +1938,7 @@ static const char * xcb_atomnames = { "Abs MT Position Y\0" "Abs MT Touch Major\0" "Abs MT Touch Minor\0" + "Abs MT Orientation\0" "Abs MT Pressure\0" "Abs MT Tracking ID\0" "Max Contacts\0" @@ -2224,13 +2233,15 @@ void QXcbConnection::initializeXKB() #endif } +#if defined(XCB_USE_XINPUT22) bool QXcbConnection::xi2MouseEvents() const { static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); - // Don't use XInput2 when Xinerama extension is enabled, - // because it causes problems with multi-monitor setup. + // FIXME: Don't use XInput2 mouse events when Xinerama extension + // is enabled, because it causes problems with multi-monitor setup. return mouseViaXI2 && !has_xinerama_extension; } +#endif #if defined(XCB_USE_XINPUT2) static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 839b51fc49..6a2ecacd77 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -267,6 +267,7 @@ namespace QXcbAtom { AbsMTPositionY, AbsMTTouchMajor, AbsMTTouchMinor, + AbsMTOrientation, AbsMTPressure, AbsMTTrackingID, MaxContacts, @@ -353,8 +354,10 @@ public: virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} +#ifdef XCB_USE_XINPUT22 virtual void handleXIMouseEvent(xcb_ge_event_t *) {} - + virtual void handleXIEnterLeave(xcb_ge_event_t *) {} +#endif virtual QXcbWindow *toWindow() { return 0; } }; @@ -491,8 +494,8 @@ public: static bool xEmbedSystemTrayAvailable(); static bool xEmbedSystemTrayVisualHasAlphaChannel(); -#ifdef XCB_USE_XINPUT2 - void handleEnterEvent(const xcb_enter_notify_event_t *); +#ifdef XCB_USE_XINPUT21 + void handleEnterEvent(); #endif #ifdef XCB_USE_XINPUT22 @@ -506,7 +509,9 @@ public: QXcbGlIntegration *glIntegration() const { return m_glIntegration; } +#ifdef XCB_USE_XINPUT22 bool xi2MouseEvents() const; +#endif protected: bool event(QEvent *e) Q_DECL_OVERRIDE; @@ -540,9 +545,9 @@ private: void initializeScreens(); bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; +#ifdef XCB_USE_XINPUT2 bool m_xi2Enabled; int m_xi2Minor; -#ifdef XCB_USE_XINPUT2 void initializeXInput2(); void finalizeXInput2(); void xi2SetupDevices(); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index e2bf6e8eb4..ca19c3dce8 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -54,6 +54,7 @@ struct XInput2TouchDeviceData { XInput2TouchDeviceData() : xiDeviceInfo(0) , qtTouchDevice(0) + , providesTouchOrientation(false) { } XIDeviceInfo *xiDeviceInfo; @@ -65,6 +66,7 @@ struct XInput2TouchDeviceData { QPointF firstPressedPosition; // in screen coordinates where the first point was pressed QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed QSizeF size; // device size in mm + bool providesTouchOrientation; }; void QXcbConnection::initializeXInput2() @@ -299,6 +301,11 @@ void QXcbConnection::xi2Select(xcb_window_t window) bitMask |= XI_ButtonPressMask; bitMask |= XI_ButtonReleaseMask; bitMask |= XI_MotionMask; + + // There is a check for enter/leave events in plain xcb enter/leave event handler + bitMask |= XI_EnterMask; + bitMask |= XI_LeaveMask; + qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); } XIEventMask mask; @@ -313,9 +320,12 @@ void QXcbConnection::xi2Select(xcb_window_t window) if (result != Success) qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); } -#endif // XCB_USE_XINPUT22 const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); +#else + const bool pointerSelected = false; +#endif // XCB_USE_XINPUT22 + QSet<int> tabletDevices; #ifndef QT_NO_TABLETEVENT if (!m_tabletData.isEmpty()) { @@ -419,6 +429,8 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) caps |= QTouchDevice::Position | QTouchDevice::NormalizedPosition; else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) caps |= QTouchDevice::Area; + else if (vci->label == atom(QXcbAtom::AbsMTOrientation)) + dev->providesTouchOrientation = true; else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure)) caps |= QTouchDevice::Pressure; else if (vci->label == atom(QXcbAtom::RelX)) { @@ -480,6 +492,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event); int sourceDeviceId = xiEvent->deviceid; // may be the master id xXIDeviceEvent *xiDeviceEvent = 0; + xXIEnterEvent *xiEnterEvent = 0; QXcbWindowEventListener *eventListener = 0; switch (xiEvent->evtype) { @@ -494,14 +507,16 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event); eventListener = windowEventListenerFromId(xiDeviceEvent->event); - if (eventListener) { - long result = 0; - if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result)) - return; - } sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master break; } + case XI_Enter: + case XI_Leave: { + xiEnterEvent = reinterpret_cast<xXIEnterEvent *>(event); + eventListener = windowEventListenerFromId(xiEnterEvent->event); + sourceDeviceId = xiEnterEvent->sourceid; // use the actual device id instead of the master + break; + } case XI_HierarchyChanged: xi2HandleHierachyEvent(xiEvent); return; @@ -512,11 +527,19 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) break; } + if (eventListener) { + long result = 0; + if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result)) + return; + } + #ifndef QT_NO_TABLETEVENT - for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == sourceDeviceId) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) - return; + if (!xiEnterEvent) { + for (int i = 0; i < m_tabletData.count(); ++i) { + if (m_tabletData.at(i).deviceId == sourceDeviceId) { + if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) + return; + } } } #endif // QT_NO_TABLETEVENT @@ -549,6 +572,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xi2ProcessTouch(xiDeviceEvent, platformWindow); break; } + } else if (xiEnterEvent && xi2MouseEvents() && eventListener) { + switch (xiEnterEvent->evtype) { + case XI_Enter: + case XI_Leave: + eventListener->handleXIEnterLeave(event); + break; + } } #endif // XCB_USE_XINPUT22 } @@ -580,7 +610,9 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo QXcbScreen* screen = platformWindow->xcbScreen(); qreal x = fixed1616ToReal(xiDeviceEvent->root_x); qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, d = 0.0; + qreal nx = -1.0, ny = -1.0; + qreal w = 0.0, h = 0.0; + bool majorAxisIsY = touchPoint.area.height() > touchPoint.area.width(); for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; if (classinfo->type == XIValuatorClass) { @@ -605,7 +637,24 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { ny = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - d = valuatorNormalized(value, vci) * screen->geometry().width(); + const qreal sw = screen->geometry().width(); + const qreal sh = screen->geometry().height(); + w = valuatorNormalized(value, vci) * std::sqrt(sw * sw + sh * sh); + } else if (vci->label == atom(QXcbAtom::AbsMTTouchMinor)) { + const qreal sw = screen->geometry().width(); + const qreal sh = screen->geometry().height(); + h = valuatorNormalized(value, vci) * std::sqrt(sw * sw + sh * sh); + } else if (vci->label == atom(QXcbAtom::AbsMTOrientation)) { + // Find the closest axis. + // 0 corresponds to the Y axis, vci->max to the X axis. + // Flipping over the Y axis and rotating by 180 degrees + // don't change the result, so normalize value to range + // [0, vci->max] first. + value = qAbs(value); + while (value > vci->max) + value -= 2 * vci->max; + value = qAbs(value); + majorAxisIsY = value < vci->max - value; } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure)) { touchPoint.pressure = valuatorNormalized(value, vci); @@ -622,8 +671,18 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo ny = y / screen->geometry().height(); } if (xiDeviceEvent->evtype != XI_TouchEnd) { - if (d == 0.0) - d = touchPoint.area.width(); + if (!dev->providesTouchOrientation) { + if (w == 0.0) + w = touchPoint.area.width(); + h = w; + } else { + if (w == 0.0) + w = qMax(touchPoint.area.width(), touchPoint.area.height()); + if (h == 0.0) + h = qMin(touchPoint.area.width(), touchPoint.area.height()); + if (majorAxisIsY) + qSwap(w, h); + } } switch (xiDeviceEvent->evtype) { @@ -687,7 +746,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo } dev->pointPressedPosition.remove(touchPoint.id); } - touchPoint.area = QRectF(x - d/2, y - d/2, d, d); + touchPoint.area = QRectF(x - w/2, y - h/2, w, h); touchPoint.normalPosition = QPointF(nx, ny); if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) @@ -724,6 +783,8 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) XISetMask(mask, XI_ButtonPress); XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_Motion); + XISetMask(mask, XI_Enter); + XISetMask(mask, XI_Leave); XISetMask(mask, XI_TouchBegin); XISetMask(mask, XI_TouchUpdate); XISetMask(mask, XI_TouchEnd); @@ -833,9 +894,9 @@ void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int #endif } -void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) -{ #ifdef XCB_USE_XINPUT21 +void QXcbConnection::handleEnterEvent() +{ QHash<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin(); const QHash<int, ScrollingDevice>::iterator end = m_scrollingDevices.end(); while (it != end) { @@ -851,8 +912,8 @@ void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) XIFreeDeviceInfo(xiDeviceInfo); ++it; } -#endif } +#endif void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice) { diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 68a999d55f..6e8755a220 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -180,9 +180,11 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char if (canNotGrabEnv) m_canGrab = false; + const int numParameters = parameters.size(); + m_connections.reserve(1 + numParameters / 2); m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); - for (int i = 0; i < parameters.size() - 1; i += 2) { + for (int i = 0; i < numParameters - 1; i += 2) { qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); m_connections << new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 457e58d6ef..4de7716703 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -803,9 +803,9 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) } } +#ifdef XCB_USE_XINPUT22 void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) { -#ifdef XCB_USE_XINPUT22 if (m_config && !connection()->hasXKB()) { xXIModifierInfo *mods = static_cast<xXIModifierInfo *>(modInfo); xXIGroupInfo *group = static_cast<xXIGroupInfo *>(groupInfo); @@ -821,12 +821,8 @@ void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); } } -#else - Q_UNUSED(modInfo); - Q_UNUSED(groupInfo); - Q_ASSERT(false); // this can't be -#endif } +#endif quint32 QXcbKeyboard::xkbModMask(quint16 state) { diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index ed9ab09ed8..75e6d2ec82 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -74,7 +74,9 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); +#ifdef XCB_USE_XINPUT22 void updateXKBStateFromXI(void *modInfo, void *groupInfo); +#endif #ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 848cd85b03..240a1dbc74 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -900,8 +900,13 @@ static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event return true; } uint response_type = event->response_type & ~0x80; - if (response_type == XCB_FOCUS_IN) - return true; + if (response_type == XCB_FOCUS_IN) { + // Ignore focus events that are being sent only because the pointer is over + // our window, even if the input focus is in a different window. + xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event; + if (e->detail != XCB_NOTIFY_DETAIL_POINTER) + return true; + } /* We are also interested in XEMBED_FOCUS_IN events */ if (response_type == XCB_CLIENT_MESSAGE) { @@ -2171,6 +2176,85 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, handleMouseEvent(timestamp, local, global, modifiers); } +static bool ignoreLeaveEvent(quint8 mode, quint8 detail) +{ + return (mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM + || detail == XCB_NOTIFY_DETAIL_VIRTUAL + || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL; +} + +static bool ignoreEnterEvent(quint8 mode, quint8 detail) +{ + return ((mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM + || (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB) + || detail == XCB_NOTIFY_DETAIL_VIRTUAL + || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); +} + +class EnterEventChecker +{ +public: + bool checkEvent(xcb_generic_event_t *event) + { + if (!event) + return false; + if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) + return false; + + xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; + if (ignoreEnterEvent(enter->mode, enter->detail)) + return false; + + return true; + } +}; + +void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp) +{ + connection()->setTime(timestamp); +#ifdef XCB_USE_XINPUT21 + connection()->handleEnterEvent(); +#endif + + const QPoint global = QPoint(root_x, root_y); + + if (ignoreEnterEvent(mode, detail) + || (connection()->buttons() != Qt::NoButton + && QGuiApplicationPrivate::lastCursorPosition != global)) + return; + + const QPoint local(event_x, event_y); + QWindowSystemInterface::handleEnterEvent(window(), local, global); +} + +void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp) +{ + connection()->setTime(timestamp); + + const QPoint global(root_x, root_y); + + if (ignoreLeaveEvent(mode, detail) + || (connection()->buttons() != Qt::NoButton + && QGuiApplicationPrivate::lastCursorPosition != global)) + return; + + EnterEventChecker checker; + xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); + QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; + + if (enterWindow) { + QPoint local(enter->event_x, enter->event_y); + QPoint global = QPoint(root_x, root_y); + QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); + } else { + QWindowSystemInterface::handleLeaveEvent(window()); + } + + free(enter); +} + void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { @@ -2205,12 +2289,10 @@ static inline int fixed1616ToInt(FP1616 val) { return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); } -#endif // With XI 2.2+ press/release/motion comes here instead of the above handlers. void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) { -#ifdef XCB_USE_XINPUT22 QXcbConnection *conn = connection(); xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event); const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); @@ -2248,12 +2330,41 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; break; } -#else - Q_UNUSED(event); - Q_ASSERT(false); // this can't be -#endif } +// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events +void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) +{ + xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event); + + // Compare the window with current mouse grabber to prevent deliver events to any other windows. + // If leave event occurs and the window is under mouse - allow to deliver the leave event. + QXcbWindow *mouseGrabber = connection()->mouseGrabber(); + if (mouseGrabber && mouseGrabber != this + && (ev->evtype != XI_Leave || QGuiApplicationPrivate::currentMouseWindow != window())) { + return; + } + + const int root_x = fixed1616ToInt(ev->root_x); + const int root_y = fixed1616ToInt(ev->root_y); + + switch (ev->evtype) { + case XI_Enter: { + const int event_x = fixed1616ToInt(ev->event_x); + const int event_y = fixed1616ToInt(ev->event_y); + qCDebug(lcQpaXInput, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d", event_x, event_y, ev->mode, ev->detail, ev->time); + handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time); + break; + } + case XI_Leave: + qCDebug(lcQpaXInput, "XI2 mouse leave, mode %d, detail %d, time %d", ev->mode, ev->detail, ev->time); + connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group); + handleLeaveNotifyEvent(root_x, root_y, ev->mode, ev->detail, ev->time); + break; + } +} +#endif + QXcbWindow *QXcbWindow::toWindow() { return this; } void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) @@ -2262,74 +2373,14 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); } -static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event) -{ - return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL - || event->mode == XCB_NOTIFY_MODE_GRAB; -} - -static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event) -{ - return (event->mode != XCB_NOTIFY_MODE_NORMAL - || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); -} - -class EnterEventChecker -{ -public: - bool checkEvent(xcb_generic_event_t *event) - { - if (!event) - return false; - if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) - return false; - - xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; - if (ignoreEnterEvent(enter)) - return false; - - return true; - } -}; - void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) { - connection()->setTime(event->time); -#ifdef XCB_USE_XINPUT2 - connection()->handleEnterEvent(event); -#endif - - if (ignoreEnterEvent(event)) - return; - - const QPoint local(event->event_x, event->event_y); - QPoint global = QPoint(event->root_x, event->root_y); - QWindowSystemInterface::handleEnterEvent(window(), local, global); + handleEnterNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->mode, event->detail, event->time); } void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) { - connection()->setTime(event->time); - - if (ignoreLeaveEvent(event)) - return; - - EnterEventChecker checker; - xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); - QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; - - if (enterWindow) { - QPoint local(enter->event_x, enter->event_y); - QPoint global = QPoint(event->root_x, event->root_y); - - QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); - } else { - QWindowSystemInterface::handleLeaveEvent(window()); - } - - free(enter); + handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time); } void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) @@ -2383,14 +2434,22 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev } } -void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) +void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event) { + // Ignore focus events that are being sent only because the pointer is over + // our window, even if the input focus is in a different window. + if (event->detail == XCB_NOTIFY_DETAIL_POINTER) + return; doFocusIn(); } -void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) +void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *event) { + // Ignore focus events that are being sent only because the pointer is over + // our window, even if the input focus is in a different window. + if (event->detail == XCB_NOTIFY_DETAIL_POINTER) + return; doFocusOut(); } @@ -2433,7 +2492,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) if (!grab && connection()->mouseGrabber() == this) connection()->setMouseGrabber(Q_NULLPTR); #ifdef XCB_USE_XINPUT22 - if (connection()->xi2MouseEvents()) { + if (connection()->isAtLeastXI22() && connection()->xi2MouseEvents()) { bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab); if (grab && result) connection()->setMouseGrabber(this); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 0efd78452c..72688cdf16 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -138,7 +138,10 @@ public: void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; +#ifdef XCB_USE_XINPUT22 void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; + void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE; +#endif QXcbWindow *toWindow() Q_DECL_OVERRIDE; @@ -219,6 +222,12 @@ protected: void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp); + + void handleLeaveNotifyEvent(int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp); + xcb_window_t m_window; uint m_depth; |