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>bb10
parent
60457e6cd0
commit
c427ba53aa
|
|
@ -98,6 +98,12 @@ QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference);
|
||||||
QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference);
|
QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference);
|
||||||
|
|
||||||
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
|
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
|
// strip out '&' characters, and convert "&&" to a single '&', in menu
|
||||||
// text - since menu text is sometimes decorated with these for Windows
|
// text - since menu text is sometimes decorated with these for Windows
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,77 @@ Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
|
||||||
return Qt::NoButton;
|
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)
|
QString qt_mac_removeAmpersandEscapes(QString s)
|
||||||
{
|
{
|
||||||
return QPlatformTheme::removeMnemonics(s).trimmed();
|
return QPlatformTheme::removeMnemonics(s).trimmed();
|
||||||
|
|
|
||||||
|
|
@ -207,18 +207,21 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
||||||
if (!target)
|
if (!target)
|
||||||
return NSDragOperationNone;
|
return NSDragOperationNone;
|
||||||
|
|
||||||
// update these so selecting move/copy/link works
|
const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
|
||||||
QGuiApplicationPrivate::modifier_buttons = [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());
|
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||||
if (nativeDrag->currentDrag()) {
|
if (nativeDrag->currentDrag()) {
|
||||||
// The drag was started from within the application
|
// 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];
|
[self updateCursorFromDragResponse:response drag:nativeDrag];
|
||||||
} else {
|
} else {
|
||||||
QCocoaDropData mimeData([sender draggingPasteboard]);
|
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());
|
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);
|
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
||||||
|
|
||||||
// Send 0 mime data to indicate drag exit
|
// 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.
|
// 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);
|
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
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()) {
|
if (nativeDrag->currentDrag()) {
|
||||||
// The drag was started from within the application
|
// 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 {
|
} else {
|
||||||
QCocoaDropData mimeData([sender draggingPasteboard]);
|
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();
|
return response.isAccepted();
|
||||||
}
|
}
|
||||||
|
|
@ -271,7 +282,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
||||||
operation:(NSDragOperation)operation
|
operation:(NSDragOperation)operation
|
||||||
{
|
{
|
||||||
Q_UNUSED(session);
|
Q_UNUSED(session);
|
||||||
Q_UNUSED(operation);
|
Q_UNUSED(screenPoint);
|
||||||
|
|
||||||
if (!m_platformWindow)
|
if (!m_platformWindow)
|
||||||
return;
|
return;
|
||||||
|
|
@ -283,20 +294,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||||
nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
|
nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
|
||||||
|
|
||||||
// keep our state, and QGuiApplication state (buttons member) in-sync,
|
m_buttons = currentlyPressedMouseButtons();
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -201,9 +201,14 @@
|
||||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||||
nativeDrag->setLastMouseEvent(theEvent, self);
|
nativeDrag->setLastMouseEvent(theEvent, self);
|
||||||
|
|
||||||
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
|
const auto modifiers = [QNSView convertKeyModifiers:theEvent.modifierFlags];
|
||||||
QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint,
|
const auto buttons = currentlyPressedMouseButtons();
|
||||||
m_buttons, keyboardModifiers, Qt::MouseEventNotSynthesized);
|
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
|
- (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue