diff options
author | Mikhail Svetkin <mikhail.svetkin@qt.io> | 2018-04-27 12:05:06 +0200 |
---|---|---|
committer | Mikhail Svetkin <mikhail.svetkin@qt.io> | 2018-05-08 11:39:32 +0000 |
commit | c427ba53aa0ee1a71aa670783f65bcfd230da653 (patch) | |
tree | a5cf855fede3d5639e2d4d182bb95809a7eb5101 /src/plugins/platforms/cocoa | |
parent | 60457e6cd04486f5503b94864d898a91a4df79e0 (diff) |
macOS: Transition to new QPA dag-and-drop API
The new API allows us to pass the mouse buttons and
keyboard modifiers along with the QWSI event.
Task-number: QTBUG-57168
Change-Id: Ic54c012d1593d922e7dcd31facab2f2c630c7996
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoahelpers.h | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoahelpers.mm | 71 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_dragging.mm | 42 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_mouse.mm | 11 |
4 files changed, 105 insertions, 25 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 516eac0503..cf8a241db5 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -98,6 +98,12 @@ QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference); QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference); Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); +Qt::MouseButton cocoaButton2QtButton(NSEvent *event); + +QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event); + +Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons); +Qt::MouseButtons currentlyPressedMouseButtons(); // strip out '&' characters, and convert "&&" to a single '&', in menu // text - since menu text is sometimes decorated with these for Windows diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index a1cf1bc632..12be222ab3 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -278,6 +278,77 @@ Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) return Qt::NoButton; } +/*! + \fn Qt::MouseButton cocoaButton2QtButton(NSEvent *event) + + Returns the Qt::Button that corresponds to an NSEvent.buttonNumber. + + \note AppKit will use buttonNumber 0 to indicate both "left button" + and "no button". Only NSEvents that describes mouse press/release/dragging + events (e.g NSEventTypeOtherMouseDown) will contain a valid + button number. +*/ +Qt::MouseButton cocoaButton2QtButton(NSEvent *event) +{ + if (event.type == NSMouseMoved) + return Qt::NoButton; + + return cocoaButton2QtButton(event.buttonNumber); +} + +/*! + \fn QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event) + + Returns the QEvent::Type that corresponds to an NSEvent.type. +*/ +QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event) +{ + switch (event.type) { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + return QEvent::MouseButtonPress; + + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + return QEvent::MouseButtonRelease; + + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + return QEvent::MouseMove; + + case NSMouseMoved: + return QEvent::MouseMove; + + default: + break; + } + + return QEvent::None; +} + +/*! + \fn Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons) + + Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons. +*/ +Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons) +{ + return static_cast<Qt::MouseButton>(pressedMouseButtons & Qt::MouseButtonMask); +} + +/*! + \fn Qt::MouseButtons currentlyPressedMouseButtons() + + Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons. +*/ +Qt::MouseButtons currentlyPressedMouseButtons() +{ + return cocoaMouseButtons2QtMouseButtons(NSEvent.pressedMouseButtons); +} + QString qt_mac_removeAmpersandEscapes(QString s) { return QPlatformTheme::removeMnemonics(s).trimmed(); diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm index e77a26eed0..01df0e9337 100644 --- a/src/plugins/platforms/cocoa/qnsview_dragging.mm +++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm @@ -207,18 +207,21 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin if (!target) return NSDragOperationNone; - // update these so selecting move/copy/link works - QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; + const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags]; + const auto buttons = currentlyPressedMouseButtons(); + const auto point = mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint); QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect()); QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); if (nativeDrag->currentDrag()) { // The drag was started from within the application - response = QWindowSystemInterface::handleDrag(target, nativeDrag->dragMimeData(), mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed); + response = QWindowSystemInterface::handleDrag(target, nativeDrag->dragMimeData(), + point, qtAllowed, buttons, modifiers); [self updateCursorFromDragResponse:response drag:nativeDrag]; } else { QCocoaDropData mimeData([sender draggingPasteboard]); - response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed); + response = QWindowSystemInterface::handleDrag(target, &mimeData, + point, qtAllowed, buttons, modifiers); } return qt_mac_mapDropAction(response.acceptedAction()); @@ -237,7 +240,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QPoint qt_windowPoint(windowPoint.x, windowPoint.y); // Send 0 mime data to indicate drag exit - QWindowSystemInterface::handleDrag(target, 0, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), Qt::IgnoreAction); + QWindowSystemInterface::handleDrag(target, nullptr, + mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), + Qt::IgnoreAction, Qt::NoButton, Qt::NoModifier); } // called on drop, send the drop to Qt and return if it was accepted. @@ -256,12 +261,18 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QPlatformDropQtResponse response(false, Qt::IgnoreAction); QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags]; + const auto buttons = currentlyPressedMouseButtons(); + const auto point = mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint); + if (nativeDrag->currentDrag()) { // The drag was started from within the application - response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(), mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed); + response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(), + point, qtAllowed, buttons, modifiers); } else { QCocoaDropData mimeData([sender draggingPasteboard]); - response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed); + response = QWindowSystemInterface::handleDrop(target, &mimeData, + point, qtAllowed, buttons, modifiers); } return response.isAccepted(); } @@ -271,7 +282,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin operation:(NSDragOperation)operation { Q_UNUSED(session); - Q_UNUSED(operation); + Q_UNUSED(screenPoint); if (!m_platformWindow) return; @@ -283,20 +294,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation)); - // keep our state, and QGuiApplication state (buttons member) in-sync, - // or future mouse events will be processed incorrectly - NSUInteger pmb = [NSEvent pressedMouseButtons]; - for (int buttonNumber = 0; buttonNumber < 32; buttonNumber++) { // see cocoaButton2QtButton() for the 32 value - if (!(pmb & (1 << buttonNumber))) - m_buttons &= ~cocoaButton2QtButton(buttonNumber); - } - - NSPoint windowPoint = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 1, 1)].origin; - NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; // NSView/QWindow coordinates - QPoint qtWindowPoint(nsViewPoint.x, nsViewPoint.y); - QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint(); - - QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_platformWindow->window(), target, qtWindowPoint), qtScreenPoint, m_buttons); + m_buttons = currentlyPressedMouseButtons(); } @end diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index a101b5ab6f..34ac1126ad 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -201,9 +201,14 @@ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); nativeDrag->setLastMouseEvent(theEvent, self); - Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; - QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, - m_buttons, keyboardModifiers, Qt::MouseEventNotSynthesized); + const auto modifiers = [QNSView convertKeyModifiers:theEvent.modifierFlags]; + const auto buttons = currentlyPressedMouseButtons(); + const auto button = cocoaButton2QtButton(theEvent); + const auto eventType = cocoaEvent2QtMouseEvent(theEvent); + + QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(), + timestamp, qtWindowPoint, qtScreenPoint, + buttons, button, eventType, modifiers); } - (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber |