src/gui/kernel/qcocoaview_mac.mm
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    62 #include <QFileInfo>
    62 #include <QFileInfo>
    63 #include <QFile>
    63 #include <QFile>
    64 
    64 
    65 #include <qdebug.h>
    65 #include <qdebug.h>
    66 
    66 
    67 @interface NSEvent (DeviceDelta)
    67 @interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
    68   - (CGFloat)deviceDeltaX;
    68   - (CGFloat)deviceDeltaX;
    69   - (CGFloat)deviceDeltaY;
    69   - (CGFloat)deviceDeltaY;
    70   - (CGFloat)deviceDeltaZ;
    70   - (CGFloat)deviceDeltaZ;
       
    71 @end
       
    72 
       
    73 @interface NSEvent (Qt_Compile_Leopard_Gestures)
       
    74   - (CGFloat)magnification;
    71 @end
    75 @end
    72 
    76 
    73 QT_BEGIN_NAMESPACE
    77 QT_BEGIN_NAMESPACE
    74 
    78 
    75 Q_GLOBAL_STATIC(DnDParams, qMacDnDParams);
    79 Q_GLOBAL_STATIC(DnDParams, qMacDnDParams);
    77 extern void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos); // qcursor_mac.mm
    81 extern void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos); // qcursor_mac.mm
    78 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp
    82 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp
    79 extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm
    83 extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm
    80 extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp
    84 extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp
    81 extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm
    85 extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm
       
    86 extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
    82 
    87 
    83 Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
    88 Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
    84 {
    89 {
    85     if (buttonNum == 0)
    90     if (buttonNum == 0)
    86         return Qt::LeftButton;
    91         return Qt::LeftButton;
   689     }
   694     }
   690 }
   695 }
   691 
   696 
   692 - (void)mouseDown:(NSEvent *)theEvent
   697 - (void)mouseDown:(NSEvent *)theEvent
   693 {
   698 {
       
   699     if (!qt_button_down)
       
   700         qt_button_down = qwidget;
       
   701 
   694     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton);
   702     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton);
   695     // Don't call super here. This prevents us from getting the mouseUp event,
   703     // Don't call super here. This prevents us from getting the mouseUp event,
   696     // which we need to send even if the mouseDown event was not accepted.
   704     // which we need to send even if the mouseDown event was not accepted.
   697     // (this is standard Qt behavior.)
   705     // (this is standard Qt behavior.)
   698 }
   706 }
   699 
   707 
   700 
   708 
   701 - (void)mouseUp:(NSEvent *)theEvent
   709 - (void)mouseUp:(NSEvent *)theEvent
   702 {
   710 {
   703     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton);
   711     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton);
   704 
   712 
   705     if (!mouseOK)
   713     qt_button_down = 0;
   706         [super mouseUp:theEvent];
       
   707 }
   714 }
   708 
   715 
   709 - (void)rightMouseDown:(NSEvent *)theEvent
   716 - (void)rightMouseDown:(NSEvent *)theEvent
   710 {
   717 {
   711     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton);
   718     if (!qt_button_down)
   712 
   719         qt_button_down = qwidget;
   713     if (!mouseOK)
   720 
   714         [super rightMouseDown:theEvent];
   721     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton);
   715 }
   722 }
   716 
   723 
   717 - (void)rightMouseUp:(NSEvent *)theEvent
   724 - (void)rightMouseUp:(NSEvent *)theEvent
   718 {
   725 {
   719     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton);
   726     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton);
   720 
   727 
   721     if (!mouseOK)
   728     qt_button_down = 0;
   722         [super rightMouseUp:theEvent];
       
   723 }
   729 }
   724 
   730 
   725 - (void)otherMouseDown:(NSEvent *)theEvent
   731 - (void)otherMouseDown:(NSEvent *)theEvent
   726 {
   732 {
       
   733     if (!qt_button_down)
       
   734         qt_button_down = qwidget;
       
   735 
   727     Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
   736     Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
   728     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, mouseButton);
   737     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, mouseButton);
   729 
       
   730     if (!mouseOK)
       
   731         [super otherMouseDown:theEvent];
       
   732 }
   738 }
   733 
   739 
   734 - (void)otherMouseUp:(NSEvent *)theEvent
   740 - (void)otherMouseUp:(NSEvent *)theEvent
   735 {
   741 {
   736     Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
   742     Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
   737     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent,  QEvent::MouseButtonRelease, mouseButton);
   743     qt_mac_handleMouseEvent(self, theEvent,  QEvent::MouseButtonRelease, mouseButton);
   738 
   744 
   739     if (!mouseOK)
   745     qt_button_down = 0;
   740         [super otherMouseUp:theEvent];
       
   741 
       
   742 }
   746 }
   743 
   747 
   744 - (void)mouseDragged:(NSEvent *)theEvent
   748 - (void)mouseDragged:(NSEvent *)theEvent
   745 {
   749 {
   746     qMacDnDParams()->view = self;
   750     qMacDnDParams()->view = self;
   747     qMacDnDParams()->theEvent = theEvent;
   751     qMacDnDParams()->theEvent = theEvent;
   748     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::LeftButton);
   752     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
   749 
       
   750     if (!mouseOK)
       
   751         [super mouseDragged:theEvent];
       
   752 }
   753 }
   753 
   754 
   754 - (void)rightMouseDragged:(NSEvent *)theEvent
   755 - (void)rightMouseDragged:(NSEvent *)theEvent
   755 {
   756 {
   756     qMacDnDParams()->view = self;
   757     qMacDnDParams()->view = self;
   757     qMacDnDParams()->theEvent = theEvent;
   758     qMacDnDParams()->theEvent = theEvent;
   758     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::RightButton);
   759     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
   759 
       
   760     if (!mouseOK)
       
   761         [super rightMouseDragged:theEvent];
       
   762 }
   760 }
   763 
   761 
   764 - (void)otherMouseDragged:(NSEvent *)theEvent
   762 - (void)otherMouseDragged:(NSEvent *)theEvent
   765 {
   763 {
   766     qMacDnDParams()->view = self;
   764     qMacDnDParams()->view = self;
   767     qMacDnDParams()->theEvent = theEvent;
   765     qMacDnDParams()->theEvent = theEvent;
   768     Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]);
   766     qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
   769     bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, mouseButton);
       
   770 
       
   771     if (!mouseOK)
       
   772         [super otherMouseDragged:theEvent];
       
   773 }
   767 }
   774 
   768 
   775 - (void)scrollWheel:(NSEvent *)theEvent
   769 - (void)scrollWheel:(NSEvent *)theEvent
   776 {
   770 {
   777     // Give the Input Manager a chance to process the wheel event.
   771     // Give the Input Manager a chance to process the wheel event.
   782 
   776 
   783     NSPoint windowPoint = [theEvent locationInWindow];
   777     NSPoint windowPoint = [theEvent locationInWindow];
   784     NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
   778     NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
   785     NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
   779     NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
   786     QPoint qlocal = QPoint(localPoint.x, localPoint.y);
   780     QPoint qlocal = QPoint(localPoint.x, localPoint.y);
   787     QPoint qglobal = QPoint(globalPoint.x, globalPoint.y);
   781     QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y));
   788     Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
   782     Qt::MouseButtons buttons = QApplication::mouseButtons();
   789     bool wheelOK = false;
   783     bool wheelOK = false;
   790     Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
   784     Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
   791     QWidget *widgetToGetMouse = qwidget;
   785     QWidget *widgetToGetMouse = qwidget;
       
   786     // if popup is open it should get wheel events if the cursor is over the popup,
       
   787     // otherwise the event should be ignored.
       
   788     if (QWidget *popup = qAppInstance()->activePopupWidget()) {
       
   789         if (!popup->geometry().contains(qglobal))
       
   790             return;
       
   791     }
       
   792 
   792     int deltaX = 0;
   793     int deltaX = 0;
   793     int deltaY = 0;
   794     int deltaY = 0;
   794     int deltaZ = 0;
   795     int deltaZ = 0;
   795 
   796 
   796     const EventRef carbonEvent = (EventRef)[theEvent eventRef];
   797     const EventRef carbonEvent = (EventRef)[theEvent eventRef];
   797     const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
   798     const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
   798     if (carbonEventKind == kEventMouseScroll) {
   799     const bool scrollEvent = carbonEventKind == kEventMouseScroll;
       
   800 
       
   801     if (scrollEvent) {
   799         // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
   802         // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
   800         // Since deviceDelta is delivered as pixels rather than degrees, we need to
   803         // Since deviceDelta is delivered as pixels rather than degrees, we need to
   801         // convert from pixels to degrees in a sensible manner.
   804         // convert from pixels to degrees in a sensible manner.
   802         // It looks like four degrees per pixel behaves most native.
   805         // It looks like four degrees per pixel behaves most native.
   803         // Qt expects the unit for delta to be 1/8 of a degree:
   806         // Qt expects the unit for delta to be 1/8 of a degree:
   804         const int scrollFactor = 4 * 8;
   807         deltaX = [theEvent deviceDeltaX];
   805         deltaX = (int)[theEvent deviceDeltaX] * scrollFactor;
   808         deltaY = [theEvent deviceDeltaY];
   806         deltaY = (int)[theEvent deviceDeltaY] * scrollFactor;
   809         deltaZ = [theEvent deviceDeltaZ];
   807         deltaZ = (int)[theEvent deviceDeltaZ] * scrollFactor;
   810     } else {
   808     } else { // carbonEventKind == kEventMouseWheelMoved
   811         // carbonEventKind == kEventMouseWheelMoved
   809         // Mouse wheel deltas seem to tick in at increments of 0.1.
   812         // Remove acceleration, and use either -120 or 120 as delta:
   810         // Qt widgets expect the delta to be a multiple of 120.
   813         deltaX = qBound(-120, int([theEvent deltaX] * 10000), 120);
   811         const int scrollFactor = 10 * 120;
   814         deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120);
   812         deltaX = [theEvent deltaX] * scrollFactor;
   815         deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120);
   813         deltaY = [theEvent deltaY] * scrollFactor;
       
   814         deltaZ = [theEvent deltaZ] * scrollFactor;
       
   815     }
   816     }
   816 
   817 
   817     if (deltaX != 0) {
   818     if (deltaX != 0) {
   818         QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);
   819         QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal);
   819         qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
   820         qt_sendSpontaneousEvent(widgetToGetMouse, &qwe);
   892 - (void)touchesCancelledWithEvent:(NSEvent *)event;
   893 - (void)touchesCancelledWithEvent:(NSEvent *)event;
   893 {
   894 {
   894     bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
   895     bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
   895     qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
   896     qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
   896 }
   897 }
       
   898 #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
   897 
   899 
   898 - (void)magnifyWithEvent:(NSEvent *)event;
   900 - (void)magnifyWithEvent:(NSEvent *)event;
   899 {
   901 {
   900     if (!QApplicationPrivate::tryModalHelper(qwidget, 0))
   902     if (!QApplicationPrivate::tryModalHelper(qwidget, 0))
   901         return;
   903         return;
   962     qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
   964     qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
   963     NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
   965     NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]];
   964     qNGEvent.position = flipPoint(p).toPoint();
   966     qNGEvent.position = flipPoint(p).toPoint();
   965     qt_sendSpontaneousEvent(qwidget, &qNGEvent);
   967     qt_sendSpontaneousEvent(qwidget, &qNGEvent);
   966 }
   968 }
   967 #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
       
   968 
   969 
   969 - (void)frameDidChange:(NSNotification *)note
   970 - (void)frameDidChange:(NSNotification *)note
   970 {
   971 {
   971     Q_UNUSED(note);
   972     Q_UNUSED(note);
   972     if (qwidget->isWindow())
   973     if (qwidget->isWindow())
  1446                         offset:mouseOffset
  1447                         offset:mouseOffset
  1447                          event:dndParams.theEvent
  1448                          event:dndParams.theEvent
  1448                     pasteboard:pboard
  1449                     pasteboard:pboard
  1449                         source:dndParams.view
  1450                         source:dndParams.view
  1450                      slideBack:YES];
  1451                      slideBack:YES];
       
  1452     // reset the implicit grab widget when drag ends because we will not
       
  1453     // receive the mouse release event when DND is active.
       
  1454     qt_button_down = 0;
  1451     [dndParams.view release];
  1455     [dndParams.view release];
  1452     [image release];
  1456     [image release];
  1453     dragPrivate()->executed_action = Qt::IgnoreAction;
  1457     dragPrivate()->executed_action = Qt::IgnoreAction;
  1454     object = 0;
  1458     object = 0;
  1455     Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams.performedAction));
  1459     Qt::DropAction performedAction(qt_mac_mapNSDragOperation(qMacDnDParams()->performedAction));
  1456     // do post drag processing, if required.
  1460     // do post drag processing, if required.
  1457     if(performedAction != Qt::IgnoreAction) {
  1461     if(performedAction != Qt::IgnoreAction) {
  1458         // check if the receiver points us to a file location.
  1462         // check if the receiver points us to a file location.
  1459         // if so, we need to do the file copy/move ourselves.
  1463         // if so, we need to do the file copy/move ourselves.
  1460         QCFType<CFURLRef> pasteLocation = 0;
  1464         QCFType<CFURLRef> pasteLocation = 0;