Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.10.1, 5.11.0
-
None
-
-
cd08753d3e2ac02663ba0ab588d7d926f7438475
Description
Any Qt application using drag and drop triggers the new 'Accessibility Access' security dialog on macOS Mojave. See attached screencast screencast.mov
Steps to reproduce:
- Download the attached application testDragDrop.app.zip testDragDrop.app.zip. Source code is also attached testDragDrop_src.zip
- Run the application on macOS Mojave
- Select any row and perform a drag operation
Result: You see the 'Accessibility Access' security dialog asking the user to allow the application.
Note: In order to see again the dialog, you can reset it by typing in the Terminal:
sudo tccutil reset PostEvent
macOS Mojave added a new security mechanism to prevent an application to control another application using CGEventPost without the user consent. When a CGEventPost event is posted, you will see a dialog asking you to allow the application in the Accessibility preferences in the System Preferences:
You can find more information about this new mechanism in the session 702 from the WWDC 2018: https://developer.apple.com/videos/play/wwdc2018/702/
When a drag occurs, QNSView creates a fake move event. This causes the new macOS security mechanism to be triggered. See in Src/qtbase/src/plugins/platforms/cocoa/qnsview.mm in the function:
- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor // by creating a fake move event if (m_updatingDrag) return; const QPoint mousePos(QCursor::pos()); CGEventRef moveEvent(CGEventCreateMouseEvent( NULL, kCGEventMouseMoved, CGPointMake(mousePos.x(), mousePos.y()), kCGMouseButtonLeft // ignored )); CGEventPost(kCGHIDEventTap, moveEvent); CFRelease(moveEvent);
Here is a backtrace where you see when the CGEventPost is sent:
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x00007fff7520fcc5 SkyLight`SLEventPost
frame #1: 0x0000000104298584 libqcocoa.dylib`-[QNSView updateCursorFromDragResponse:drag:] + 580
frame #2: 0x0000000104298868 libqcocoa.dylib`-[QNSView handleDrag:] + 600
frame #3: 0x00007fff4c9cf61e AppKit`-[NSDragDestination _draggingEntered] + 54
frame #4: 0x00007fff4c6dfa98 AppKit`NSCoreDragTrackingProc + 1007
frame #5: 0x00007fff4d6b0b7a HIServices`DoTrackingMessage + 409
frame #6: 0x00007fff4d6b0fc6 HIServices`DragInApplication + 244
frame #7: 0x00007fff4d6afff0 HIServices`CoreDragStartDragging + 955
frame #8: 0x00007fff4c6defa7 AppKit`-[NSCoreDragManager _dragUntilMouseUp:accepted:] + 1238
frame #9: 0x00007fff4c6dc029 AppKit`-[NSCoreDragManager dragImage:fromWindow:at:offset:event:pasteboard:source:slideBack:] + 2992
frame #10: 0x00007fff4c6db467 AppKit`-[NSWindow(NSDrag) dragImage:at:offset:event:pasteboard:source:slideBack:] + 132
frame #11: 0x00000001042b3d36 libqcocoa.dylib`QCocoaDrag::drag(QDrag*) + 694
frame #12: 0x00000001006c972d QtGui`QDragManager::drag(QDrag*) + 189
frame #13: 0x00000001006c8cb8 QtGui`QDrag::exec(QFlags<Qt::DropAction>, Qt::DropAction) + 88
frame #14: 0x000000010036d314 QtWidgets`QAbstractItemView::startDrag(QFlags<Qt::DropAction>) + 292
frame #15: 0x0000000100363df5 QtWidgets`QAbstractItemView::mouseMoveEvent(QMouseEvent*) + 421
frame #16: 0x00000001003d2e57 QtWidgets`QTreeView::mouseMoveEvent(QMouseEvent*) + 199
frame #17: 0x0000000100137120 QtWidgets`QWidget::event(QEvent*) + 544
frame #18: 0x00000001001e07cd QtWidgets`QFrame::event(QEvent*) + 45
frame #19: 0x00000001001ea869 QtWidgets`QAbstractScrollArea::viewportEvent(QEvent*) + 57
frame #20: 0x00000001003634fe QtWidgets`QAbstractItemView::viewportEvent(QEvent*) + 1502
frame #21: 0x00000001003cf135 QtWidgets`QTreeView::viewportEvent(QEvent*) + 517
frame #22: 0x00000001001eb524 QtWidgets`QAbstractScrollAreaFilter::eventFilter(QObject*, QEvent*) + 36
frame #23: 0x0000000100d71322 QtCore`QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) + 210
frame #24: 0x00000001000fcecd QtWidgets`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 285
frame #25: 0x00000001000ffc7d QtWidgets`QApplication::notify(QObject*, QEvent*) + 7165
frame #26: 0x0000000100d7103f QtCore`QCoreApplication::notifyInternal2(QObject*, QEvent*) + 159
frame #27: 0x00000001000fd810 QtWidgets`QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) + 896
frame #28: 0x0000000100157210 QtWidgets`QWidgetWindow::handleMouseEvent(QMouseEvent*) + 1744
frame #29: 0x0000000100155f00 QtWidgets`QWidgetWindow::event(QEvent*) + 224
frame #30: 0x00000001000fcee2 QtWidgets`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 306
frame #31: 0x00000001000fe1ff QtWidgets`QApplication::notify(QObject*, QEvent*) + 383
frame #32: 0x0000000100d7103f QtCore`QCoreApplication::notifyInternal2(QObject*, QEvent*) + 159
frame #33: 0x00000001006b37f9 QtGui`QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) + 3145
frame #34: 0x00000001006994db QtGui`QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 155
frame #35: 0x000000010429e2c1 libqcocoa.dylib`QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void*) + 33
frame #36: 0x00007fff4ef00fc0 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #37: 0x00007fff4ef9e472 CoreFoundation`__CFRunLoopDoSource0 + 108
frame #38: 0x00007fff4eee811a CoreFoundation`__CFRunLoopDoSources0 + 195
frame #39: 0x00007fff4eee76b7 CoreFoundation`__CFRunLoopRun + 1225
frame #40: 0x00007fff4eee6fc7 CoreFoundation`CFRunLoopRunSpecific + 463
frame #41: 0x00007fff4e1835fb HIToolbox`RunCurrentEventLoopInMode + 293
frame #42: 0x00007fff4e18323e HIToolbox`ReceiveNextEventCommon + 371
frame #43: 0x00007fff4e1830b2 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 64
frame #44: 0x00007fff4c48fa02 AppKit`_DPSNextEvent + 1000
frame #45: 0x00007fff4cbd7586 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1356
frame #46: 0x00007fff4c4850e5 AppKit`-[NSApplication run] + 699
frame #47: 0x000000010429d0bd libqcocoa.dylib`QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 2397
frame #48: 0x0000000100d6cb92 QtCore`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 418
frame #49: 0x0000000100d71752 QtCore`QCoreApplication::exec() + 402
frame #50: 0x00000001000038af testDragDrop`main(argc=1, argv=0x00007ffeefbff9f8) at main.cpp:34
frame #51: 0x00007fff7be09ee1 libdyld.dylib`start + 1
frame #52: 0x00007fff7be09ee1 libdyld.dylib`start + 1