summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-04-29 16:09:54 +0200
committerLiang Qi <liang.qi@qt.io>2016-04-29 17:55:20 +0200
commitb894a8def5d9107663e4968d2d395f5ef3059125 (patch)
treef894c50c9e5cbdd7ec102291eb94979977ce5b37 /src/plugins
parentd2304a28ca657634253af26ad803c7f292e6f4cc (diff)
parent002112e80516a29efbb6cef721d74c5fc39fc19d (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.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp19
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp12
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp67
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp55
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;