diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index ea1180fae4d..243cdb81217 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -146,14 +146,35 @@ - (void)handleMouseEvent:(NSEvent *)theEvent; { - NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil]; - QPoint qt_windowPoint(windowPoint.x, windowPoint.y); + // Calculate the mouse position in the QWindow and Qt screen coordinate system, + // starting from coordinates in the NSWindow coordinate system. + // + // This involves translating according to the window location on screen, + // as well as inverting the y coordinate due to the origin change. + // + // Coordinate system overview, outer to innermost: + // + // Name Origin + // + // OS X screen bottom-left + // Qt screen top-left + // NSWindow bottom-left + // NSView/QWindow top-left + // + // NSView and QWindow are equal coordinate systems: the QWindow covers the + // entire NSView, and we've set the NSView's isFlipped property to true. - NSTimeInterval timestamp = [theEvent timestamp]; - ulong qt_timestamp = timestamp * 1000; + NSPoint nsWindowPoint = [theEvent locationInWindow]; // NSWindow coordinates - // ### Should the points be windowPoint and screenPoint? - QWindowSystemInterface::handleMouseEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, m_buttons); + NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates + QPoint qtWindowPoint(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates + + NSRect screenRect = [[self window] convertRectToScreen : NSMakeRect(nsWindowPoint.x, nsWindowPoint.y, 0, 0)]; // OS X screen coordinates + QPoint qtScreenPoint(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y)); // Qt screen coordinates + + ulong timestamp = [theEvent timestamp] * 1000; + + QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons); } - (void)mouseDown:(NSEvent *)theEvent diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 07035e927fc..5d5098c1e28 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2865,7 +2865,7 @@ bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop) \internal */ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint &globalPos, - QPoint &pos, QEvent::Type type, + QPoint *pos, QEvent::Type type, Qt::MouseButtons buttons, QWidget *buttonDown, QWidget *alienWidget) { @@ -2887,7 +2887,7 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint if (mouseGrabber && mouseGrabber != candidate) { receiver = mouseGrabber; - pos = receiver->mapFromGlobal(globalPos); + *pos = receiver->mapFromGlobal(globalPos); #ifdef ALIEN_DEBUG qDebug() << " ** receiver adjusted to:" << receiver << "pos:" << pos; #endif diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index e451a53b6c0..2130a976fef 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -473,7 +473,7 @@ public: static QString styleSheet; #endif static QPointer leaveAfterRelease; - static QWidget *pickMouseReceiver(QWidget *candidate, const QPoint &globalPos, QPoint &pos, + static QWidget *pickMouseReceiver(QWidget *candidate, const QPoint &globalPos, QPoint *pos, QEvent::Type type, Qt::MouseButtons buttons, QWidget *buttonDown, QWidget *alienWidget); static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget, diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 44880158a8d..ee5cd7482ec 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -251,7 +251,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (event->type() == QEvent::MouseButtonPress && !qt_button_down) qt_button_down = widget; - QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->globalPos(), mapped, event->type(), event->buttons(), + QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->globalPos(), &mapped, event->type(), event->buttons(), qt_button_down, widget); if (!receiver) {