diff options
author | Liang Qi <liang.qi@qt.io> | 2016-04-29 16:09:54 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-04-29 17:55:20 +0200 |
commit | b894a8def5d9107663e4968d2d395f5ef3059125 (patch) | |
tree | f894c50c9e5cbdd7ec102291eb94979977ce5b37 /src/plugins | |
parent | d2304a28ca657634253af26ad803c7f292e6f4cc (diff) | |
parent | 002112e80516a29efbb6cef721d74c5fc39fc19d (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
mkspecs/features/qml_module.prf
mkspecs/features/qt_common.prf
src/gui/text/qzip.cpp
src/plugins/platforms/cocoa/qnsview.mm
src/plugins/platforms/windows/array.h
src/testlib/qtestcase.cpp
src/widgets/dialogs/qfilesystemmodel.h
Change-Id: Ie41c5868415b81f7693c80e045497035504bb210
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenu.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 6 | ||||
-rw-r--r-- | src/plugins/platforms/windows/accessible/iaccessible2.cpp | 19 | ||||
-rw-r--r-- | src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsinputcontext.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtfileengine.cpp | 12 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 67 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 55 |
8 files changed, 112 insertions, 57 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 0690a8e0fa..a388155c03 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -105,7 +105,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (NSInteger)numberOfItemsInMenu:(NSMenu *)menu { Q_ASSERT(m_menu->nsMenu() == menu); - return m_menu->items().count(); + return menu.numberOfItems; } - (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 908277a1e3..697cece77f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -747,8 +747,7 @@ QT_WARNING_POP - (void)handleMouseEvent:(NSEvent *)theEvent { - if ([self handleTabletEvent: theEvent]) - return; + bool isTabletEvent = [self handleTabletEvent: theEvent]; QPointF qtWindowPoint; QPointF qtScreenPoint; @@ -777,7 +776,8 @@ QT_WARNING_POP nativeDrag->setLastMouseEvent(theEvent, self); Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; - QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers); + QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers, + isTabletEvent ? Qt::MouseEventSynthesizedByQt : Qt::MouseEventNotSynthesized); } - (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index f34649e327..5ba49a8a98 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -45,6 +45,7 @@ #include <QtGui/qaccessible.h> #include <QtGui/qclipboard.h> #include <QtGui/qguiapplication.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <QtCore/qdebug.h> #include <algorithm> @@ -607,7 +608,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex // The IDL documents that the client must free with CoTaskMemFree arrayOfBindingsToReturn = coTaskMemAllocArray<BSTR>(numBindings); std::transform(keyBindings.constBegin(), keyBindings.constEnd(), - arrayOfBindingsToReturn, QStringToBSTR); + QT_MAKE_CHECKED_ARRAY_ITERATOR(arrayOfBindingsToReturn, numBindings), + QStringToBSTR); } } *keyBindings = arrayOfBindingsToReturn; @@ -666,9 +668,11 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, l QAccessibleInterface *parentIface = accessible->parent(); if (parentIface && parentIface->isValid()) topLeft -= parentIface->rect().topLeft(); + const QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, accessible->window()); - *x = topLeft.x(); - *y = topLeft.y(); + + *x = nativeTopLeft.x(); + *y = nativeTopLeft.y(); return S_OK; } @@ -989,7 +993,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele *selectedColumns = Q_NULLPTR; if (count) { *selectedColumns = coTaskMemAllocArray<long>(count); - std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedColumns, count)); } return count ? S_OK : S_FALSE; } @@ -1011,7 +1016,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte *selectedRows = Q_NULLPTR; if (count) { *selectedRows = coTaskMemAllocArray<long>(count); - std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows); + std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedRows, count)); } return count ? S_OK : S_FALSE; } @@ -1680,7 +1686,8 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface* if (count) { *outputAccessibles = coTaskMemAllocArray<IUnknown *>(count); std::transform(inputCells.constBegin(), inputCells.constEnd(), - *outputAccessibles, QWindowsAccessibility::wrap); + QT_MAKE_CHECKED_ARRAY_ITERATOR(*outputAccessibles, count), + QWindowsAccessibility::wrap); } return count > 0 ? S_OK : S_FALSE; } diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 0fff804e29..5fb06a6ed1 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -55,6 +55,7 @@ #include <QtGui/qguiapplication.h> #include <qpa/qplatformnativeinterface.h> #include <QtGui/qwindow.h> +#include <QtGui/private/qhighdpiscaling_p.h> //#include <uiautomationcoreapi.h> #ifndef UiaRootObjectId @@ -503,7 +504,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT if (!accessible) return E_FAIL; - QAccessibleInterface *child = accessible->childAt(xLeft, yTop); + const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window()); + QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y()); if (child == 0) { // no child found, return this item if it contains the coordinates if (accessible->rect().contains(xLeft, yTop)) { @@ -545,7 +547,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long QAccessibleInterface *acc = childPointer(accessible, varID); if (!acc || !acc->isValid()) return E_FAIL; - const QRect rect = acc->rect(); + const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window()); *pxLeft = rect.x(); *pyTop = rect.y(); diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index ea68ba8cab..501b956a68 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -654,7 +654,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) reconv->dwTargetStrOffset = reconv->dwCompStrOffset; ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1); std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(), - pastReconv); + QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv)); return memSize; } diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index ad81ef4f5f..53e7ebd30d 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -466,14 +466,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen) hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); - hr = QWinRTFunctions::await(op, buffer.GetAddressOf()); + // Quoting MSDN IInputStream::ReadAsync() documentation: + // "Depending on the implementation, the data that's read might be placed + // into the input buffer, or it might be returned in a different buffer." + // Using GetAddressOf can cause ref counting errors leaking the original + // buffer. + ComPtr<IBuffer> effectiveBuffer; + hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf()); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); - hr = buffer->get_Length(&length); + hr = effectiveBuffer->get_Length(&length); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess; - hr = buffer.As(&byteArrayAccess); + hr = effectiveBuffer.As(&byteArrayAccess); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1); byte *bytes; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index f3667aaa0d..aed33f6b48 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -955,8 +955,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args) return S_OK; } -HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *) +HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args) { + Q_D(QWinRTScreen); + + ComPtr<IPointerPoint> pointerPoint; + if (FAILED(args->get_CurrentPoint(&pointerPoint))) + return E_INVALIDARG; + + quint32 id; + if (FAILED(pointerPoint->get_PointerId(&id))) + return E_INVALIDARG; + + d->touchPoints.remove(id); + QWindowSystemInterface::handleLeaveEvent(0); return S_OK; } @@ -1040,6 +1052,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) break; } + case PointerDeviceType_Pen: case PointerDeviceType_Touch: { if (!d->touchDevice) { d->touchDevice = new QTouchDevice; @@ -1058,51 +1071,45 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) float pressure; properties->get_Pressure(&pressure); - QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id); - if (it != d->touchPoints.end()) { - boolean isPressed; + boolean isPressed; #ifndef Q_OS_WINPHONE - pointerPoint->get_IsInContact(&isPressed); + pointerPoint->get_IsInContact(&isPressed); #else - properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone + properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone #endif - it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased; - } else { + + const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor, + area.Width * d->scaleFactor, area.Height * d->scaleFactor); + + QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id); + if (it == d->touchPoints.end()) { it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint()); - it.value().state = Qt::TouchPointPressed; it.value().id = id; } - it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor, - area.Width * d->scaleFactor, area.Height * d->scaleFactor); + + if (isPressed && it.value().pressure == 0.) + it.value().state = Qt::TouchPointPressed; + else if (!isPressed && it.value().pressure > 0.) + it.value().state = Qt::TouchPointReleased; + else if (it.value().area == areaRect) + it.value().state = Qt::TouchPointStationary; + else + it.value().state = Qt::TouchPointMoved; + + it.value().area = areaRect; it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height()); it.value().pressure = pressure; QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods); - // Remove released points, station others - for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) { - if (i.value().state == Qt::TouchPointReleased) - i = d->touchPoints.erase(i); - else - (i++).value().state = Qt::TouchPointStationary; - } - - break; - } - case PointerDeviceType_Pen: { - quint32 id; - pointerPoint->get_PointerId(&id); - - boolean isPressed; - pointerPoint->get_IsInContact(&isPressed); + // Fall-through for pen to generate tablet event + if (pointerDeviceType != PointerDeviceType_Pen) + break; boolean isEraser; properties->get_IsEraser(&isEraser); int pointerType = isEraser ? 3 : 1; - float pressure; - properties->get_Pressure(&pressure); - float xTilt; properties->get_XTilt(&xTilt); diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index ea20ef7a04..1c9faa17ea 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1078,6 +1078,40 @@ void QXcbDrag::cancel() send_leave(); } +// find an ancestor with XdndAware on it +static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window) +{ + xcb_window_t target = 0; + forever { + // check if window has XdndAware + xcb_get_property_cookie_t gpCookie = Q_XCB_CALL( + xcb_get_property(c->xcb_connection(), false, window, + c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); + xcb_get_property_reply_t *gpReply = xcb_get_property_reply( + c->xcb_connection(), gpCookie, 0); + bool aware = gpReply && gpReply->type != XCB_NONE; + free(gpReply); + if (aware) { + target = window; + break; + } + + // try window's parent + xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL( + xcb_query_tree_unchecked(c->xcb_connection(), window)); + xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply( + c->xcb_connection(), qtCookie, NULL); + if (!qtReply) + break; + xcb_window_t root = qtReply->root; + xcb_window_t parent = qtReply->parent; + free(qtReply); + if (window == root) + break; + window = parent; + } + return target; +} void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event) { @@ -1105,17 +1139,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event // xcb_convert_selection() that we sent the XdndDrop event to. at = findTransactionByWindow(event->requestor); } -// if (at == -1 && event->time == XCB_CURRENT_TIME) { -// // previous Qt versions always requested the data on a child of the target window -// // using CurrentTime... but it could be asking for either drop data or the current drag's data -// Window target = findXdndAwareParent(event->requestor); -// if (target) { -// if (current_target && current_target == target) -// at = -2; -// else -// at = findXdndDropTransactionByWindow(target); -// } -// } + + if (at == -1 && event->time == XCB_CURRENT_TIME) { + xcb_window_t target = findXdndAwareParent(connection(), event->requestor); + if (target) { + if (current_target == target) + at = -2; + else + at = findTransactionByWindow(target); + } + } } QDrag *transactionDrag = 0; |