src/gui/kernel/qcocoaview_mac.mm
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
--- a/src/gui/kernel/qcocoaview_mac.mm	Tue Jan 26 12:42:25 2010 +0200
+++ b/src/gui/kernel/qcocoaview_mac.mm	Tue Feb 02 00:43:10 2010 +0200
@@ -64,12 +64,16 @@
 
 #include <qdebug.h>
 
-@interface NSEvent (DeviceDelta)
+@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
   - (CGFloat)deviceDeltaX;
   - (CGFloat)deviceDeltaY;
   - (CGFloat)deviceDeltaZ;
 @end
 
+@interface NSEvent (Qt_Compile_Leopard_Gestures)
+  - (CGFloat)magnification;
+@end
+
 QT_BEGIN_NAMESPACE
 
 Q_GLOBAL_STATIC(DnDParams, qMacDnDParams);
@@ -79,6 +83,7 @@
 extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm
 extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp
 extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
 
 Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
 {
@@ -691,6 +696,9 @@
 
 - (void)mouseDown:(NSEvent *)theEvent
 {
+    if (!qt_button_down)
+        qt_button_down = qwidget;
+
     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton);
     // Don't call super here. This prevents us from getting the mouseUp event,
     // which we need to send even if the mouseDown event was not accepted.
@@ -700,76 +708,62 @@
 
 - (void)mouseUp:(NSEvent *)theEvent
 {
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton);
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton);
 
-    if (!mouseOK)
-        [super mouseUp:theEvent];
+    qt_button_down = 0;
 }
 
 - (void)rightMouseDown:(NSEvent *)theEvent
 {
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton);
+    if (!qt_button_down)
+        qt_button_down = qwidget;
 
-    if (!mouseOK)
-        [super rightMouseDown:theEvent];
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton);
 }
 
 - (void)rightMouseUp:(NSEvent *)theEvent
 {
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton);
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton);
 
-    if (!mouseOK)
-        [super rightMouseUp:theEvent];
+    qt_button_down = 0;
 }
 
 - (void)otherMouseDown:(NSEvent *)theEvent
 {
-    Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, mouseButton);
+    if (!qt_button_down)
+        qt_button_down = qwidget;
 
-    if (!mouseOK)
-        [super otherMouseDown:theEvent];
+    Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, mouseButton);
 }
 
 - (void)otherMouseUp:(NSEvent *)theEvent
 {
     Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent,  QEvent::MouseButtonRelease, mouseButton);
+    qt_mac_handleMouseEvent(self, theEvent,  QEvent::MouseButtonRelease, mouseButton);
 
-    if (!mouseOK)
-        [super otherMouseUp:theEvent];
-
+    qt_button_down = 0;
 }
 
 - (void)mouseDragged:(NSEvent *)theEvent
 {
     qMacDnDParams()->view = self;
     qMacDnDParams()->theEvent = theEvent;
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::LeftButton);
-
-    if (!mouseOK)
-        [super mouseDragged:theEvent];
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
 }
 
 - (void)rightMouseDragged:(NSEvent *)theEvent
 {
     qMacDnDParams()->view = self;
     qMacDnDParams()->theEvent = theEvent;
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::RightButton);
-
-    if (!mouseOK)
-        [super rightMouseDragged:theEvent];
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
 }
 
 - (void)otherMouseDragged:(NSEvent *)theEvent
 {
     qMacDnDParams()->view = self;
     qMacDnDParams()->theEvent = theEvent;
-    Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
-    bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, mouseButton);
-
-    if (!mouseOK)
-        [super otherMouseDragged:theEvent];
+    qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
 }
 
 - (void)scrollWheel:(NSEvent *)theEvent
@@ -784,34 +778,41 @@
     NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
     NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
     QPoint qlocal = QPoint(localPoint.x, localPoint.y);
-    QPoint qglobal = QPoint(globalPoint.x, globalPoint.y);
-    Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
+    QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y));
+    Qt::MouseButtons buttons = QApplication::mouseButtons();
     bool wheelOK = false;
     Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
     QWidget *widgetToGetMouse = qwidget;
+    // if popup is open it should get wheel events if the cursor is over the popup,
+    // otherwise the event should be ignored.
+    if (QWidget *popup = qAppInstance()->activePopupWidget()) {
+        if (!popup->geometry().contains(qglobal))
+            return;
+    }
+
     int deltaX = 0;
     int deltaY = 0;
     int deltaZ = 0;
 
     const EventRef carbonEvent = (EventRef)[theEvent eventRef];
     const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
-    if (carbonEventKind == kEventMouseScroll) {
+    const bool scrollEvent = carbonEventKind == kEventMouseScroll;
+
+    if (scrollEvent) {
         // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
         // Since deviceDelta is delivered as pixels rather than degrees, we need to
         // convert from pixels to degrees in a sensible manner.
         // It looks like four degrees per pixel behaves most native.
         // Qt expects the unit for delta to be 1/8 of a degree:
-        const int scrollFactor = 4 * 8;
-        deltaX = (int)[theEvent deviceDeltaX] * scrollFactor;
-        deltaY = (int)[theEvent deviceDeltaY] * scrollFactor;
-        deltaZ = (int)[theEvent deviceDeltaZ] * scrollFactor;
-    } else { // carbonEventKind == kEventMouseWheelMoved
-        // 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;
-        deltaX = [theEvent deltaX] * scrollFactor;
-        deltaY = [theEvent deltaY] * scrollFactor;
-        deltaZ = [theEvent deltaZ] * scrollFactor;
+        deltaX = [theEvent deviceDeltaX];
+        deltaY = [theEvent deviceDeltaY];
+        deltaZ = [theEvent deviceDeltaZ];
+    } else {
+        // carbonEventKind == kEventMouseWheelMoved
+        // Remove acceleration, and use either -120 or 120 as delta:
+        deltaX = qBound(-120, int([theEvent deltaX] * 10000), 120);
+        deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120);
+        deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120);
     }
 
     if (deltaX != 0) {
@@ -894,6 +895,7 @@
     bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
     qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
 }
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
 
 - (void)magnifyWithEvent:(NSEvent *)event;
 {
@@ -964,7 +966,6 @@
     qNGEvent.position = flipPoint(p).toPoint();
     qt_sendSpontaneousEvent(qwidget, &qNGEvent);
 }
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
 
 - (void)frameDidChange:(NSNotification *)note
 {
@@ -1448,11 +1449,14 @@
                     pasteboard:pboard
                         source:dndParams.view
                      slideBack:YES];
+    // reset the implicit grab widget when drag ends because we will not
+    // receive the mouse release event when DND is active.
+    qt_button_down = 0;
     [dndParams.view release];
     [image release];
     dragPrivate()->executed_action = Qt::IgnoreAction;
     object = 0;
-    Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams.performedAction));
+    Qt::DropAction performedAction(qt_mac_mapNSDragOperation(qMacDnDParams()->performedAction));
     // do post drag processing, if required.
     if(performedAction != Qt::IgnoreAction) {
         // check if the receiver points us to a file location.