summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qcocoaview_mac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qcocoaview_mac.mm')
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm84
1 files changed, 53 insertions, 31 deletions
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 670226b..60ac062 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -293,9 +293,18 @@ extern "C" {
QPoint posDrag(localPoint.x, localPoint.y);
NSDragOperation nsActions = [sender draggingSourceOperationMask];
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(nsActions);
+ QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ if ([sender draggingSource] != nil) {
+ // modifier flags might have changed, update it here since we don't send any input events.
+ QApplicationPrivate::modifier_buttons = qt_cocoaModifiers2QtModifiers([[NSApp currentEvent] modifierFlags]);
+ modifiers = QApplication::keyboardModifiers();
+ } else {
+ // when the source is from another application the above technique will not work.
+ modifiers = qt_cocoaDragOperation2QtModifiers(nsActions);
+ }
// send the drag enter event to the widget.
- QDragEnterEvent qDEEvent(posDrag, qtAllowed, mimeData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QDragEnterEvent qDEEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
QApplication::sendEvent(qwidget, &qDEEvent);
if (!qDEEvent.isAccepted()) {
// widget is not interested in this drag, so ignore this drop data.
@@ -303,24 +312,23 @@ extern "C" {
return NSDragOperationNone;
} else {
// send a drag move event immediately after a drag enter event (as per documentation).
- QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
qDMEvent.setDropAction(qDEEvent.dropAction());
qDMEvent.accept(); // accept by default, since enter event was accepted.
QApplication::sendEvent(qwidget, &qDMEvent);
if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) {
// since we accepted the drag enter event, the widget expects
// future drage move events.
- // ### check if we need to treat this like the drag enter event.
+ // ### check if we need to treat this like the drag enter event.
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDEEvent.dropAction());
} else {
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
- }
+ }
QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent);
- return nsActions;
+ return nsActions;
}
}
-
+
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
// drag enter event was rejected, so ignore the move event.
@@ -338,11 +346,19 @@ extern "C" {
// send drag move event to the widget
QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions);
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ if ([sender draggingSource] != nil) {
+ // modifier flags might have changed, update it here since we don't send any input events.
+ QApplicationPrivate::modifier_buttons = qt_cocoaModifiers2QtModifiers([[NSApp currentEvent] modifierFlags]);
+ modifiers = QApplication::keyboardModifiers();
+ } else {
+ // when the source is from another application the above technique will not work.
+ modifiers = qt_cocoaDragOperation2QtModifiers(nsActions);
+ }
QMimeData *mimeData = dropData;
if (QDragManager::self()->source())
mimeData = QDragManager::self()->dragPrivate()->data;
- QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
qDMEvent.accept();
QApplication::sendEvent(qwidget, &qDMEvent);
@@ -371,12 +387,12 @@ extern "C" {
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
[self addDropData:sender];
-
+
NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint posDrop(localPoint.x, localPoint.y);
-
+
NSDragOperation nsActions = [sender draggingSourceOperationMask];
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(nsActions);
QMimeData *mimeData = dropData;
@@ -388,6 +404,8 @@ extern "C" {
if (QDragManager::self()->object)
QDragManager::self()->dragPrivate()->target = qwidget;
QApplication::sendEvent(qwidget, &de);
+ if (QDragManager::self()->object)
+ QDragManager::self()->dragPrivate()->executed_action = de.dropAction();
if (!de.isAccepted())
return NO;
else
@@ -419,10 +437,9 @@ extern "C" {
- (void) setFrameSize:(NSSize)newSize
{
[super setFrameSize:newSize];
-
+
// A change in size has required the view to be invalidated.
- if ([self inLiveResize])
- {
+ if ([self inLiveResize]) {
NSRect rects[4];
NSInteger count;
[self getRectsExposedDuringLiveResize:rects count:&count];
@@ -430,9 +447,7 @@ extern "C" {
{
[self setNeedsDisplayInRect:rects[count]];
}
- }
- else
- {
+ } else {
[self setNeedsDisplay:YES];
}
}
@@ -567,7 +582,7 @@ extern "C" {
if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) {
QApplication::sendEvent(qwidget, &enterEvent);
qt_mouseover = qwidget;
-
+
// Update cursor and dispatch hover events.
qt_mac_update_cursor_at_global_pos(flipPoint(globalPoint).toPoint());
if (qwidget->testAttribute(Qt::WA_Hover) &&
@@ -622,7 +637,7 @@ extern "C" {
[viewsToLookAt addObject:qt_mac_nativeview_for(parentWidget)];
parentWidget = parentWidget->parentWidget();
}
-
+
// Now walk through the subviews of each view and determine which subview should
// get the event. We look through all the subviews at a given level with
// the assumption that the last item to be found the candidate has a higher z-order.
@@ -632,7 +647,7 @@ extern "C" {
for (NSView *lookView in viewsToLookAt) {
NSPoint tmpPoint = [lookView convertPoint:windowPoint fromView:nil];
for (NSView *view in [lookView subviews]) {
- if (view == mouseView)
+ if (view == mouseView || [view isHidden])
continue;
NSRect frameRect = [view frame];
if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
@@ -651,7 +666,7 @@ extern "C" {
NSPoint tmpPoint = [viewForDescent convertPoint:windowPoint fromView:nil];
// Apply same rule as above wrt z-order.
for (NSView *view in [viewForDescent subviews]) {
- if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
+ if (![view isHidden] && NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
lowerView = view;
}
if (!lowerView) // Low as we can be at this point.
@@ -758,7 +773,7 @@ extern "C" {
if (currentIManager && [currentIManager wantsToHandleMouseEvents]) {
[currentIManager handleMouseEvent:theEvent];
}
-
+
NSPoint windowPoint = [theEvent locationInWindow];
NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
@@ -767,7 +782,7 @@ extern "C" {
Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
bool wheelOK = false;
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
-
+
// Mouse wheel deltas seem to tick in at increments of 0.1. Qt widgets
// expect the delta to be a multiple of 120.
const int ScrollFactor = 10 * 120;
@@ -789,20 +804,20 @@ extern "C" {
wheelOK = qwe2.isAccepted();
}
}
-
+
if (deltaY) {
QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, keyMods, Qt::Vertical);
qt_sendSpontaneousEvent(qwidget, &qwe);
wheelOK = qwe.isAccepted();
- if (wheelOK && QApplicationPrivate::focus_widget
+ if (!wheelOK && QApplicationPrivate::focus_widget
&& QApplicationPrivate::focus_widget != qwidget) {
QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(qglobal), qglobal,
- deltaZ, buttons, keyMods, Qt::Vertical);
+ deltaY, buttons, keyMods, Qt::Vertical);
qt_sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
wheelOK = qwe2.isAccepted();
}
}
-
+
if (deltaZ) {
// Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to
// try to be ahead of the pack, I'm adding this extra value.
@@ -891,6 +906,11 @@ extern "C" {
Q_UNUSED(anImage);
Q_UNUSED(aPoint);
qMacDnDParams()->performedAction = operation;
+ if (QDragManager::self()->object
+ && QDragManager::self()->dragPrivate()->executed_action != Qt::ActionMask) {
+ qMacDnDParams()->performedAction =
+ qt_mac_mapDropAction(QDragManager::self()->dragPrivate()->executed_action);
+ }
}
- (QWidget *)qt_qwidget
@@ -1214,13 +1234,13 @@ Qt::DropAction QDragManager::drag(QDrag *o)
so we just bail early to prevent it */
if(!(GetCurrentEventButtonState() & kEventMouseButtonPrimary))
return Qt::IgnoreAction;
-
+
if(object) {
dragPrivate()->source->removeEventFilter(this);
cancel();
beingCancelled = false;
}
-
+
object = o;
dragPrivate()->target = 0;
@@ -1232,7 +1252,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray());
dragBoard.setMimeData(dragPrivate()->data);
-
+
// create the image
QPoint hotspot;
QPixmap pix = dragPrivate()->pixmap;
@@ -1278,6 +1298,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
NSSize mouseOffset = {0.0, 0.0};
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
NSPoint windowPoint = [dndParams->theEvent locationInWindow];
+ dragPrivate()->executed_action = Qt::ActionMask;
// do the drag
[dndParams->view retain];
[dndParams->view dragImage:image
@@ -1289,6 +1310,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
slideBack:YES];
[dndParams->view release];
[image release];
+ dragPrivate()->executed_action = Qt::IgnoreAction;
object = 0;
Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams->performedAction));
// do post drag processing, if required.