Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-29701

OSX EventDispatcher bug for drag and drop events

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P2: Important
    • None
    • 4.8.0, 5.4.1
    • GUI: Drag and Drop
    • None
    • macOS

    Description

      I have a dialog (in the attached sample it's a QMainWindow, but it also manifests with QDialogs) that accepts dropped files. When it gets a drop event it pops up a modal dialog that accepts text input. On OSX (10.7.3), this is what happens when I drag a file from Finder to my dialog:

      • Make sure the QDialog has focus (not Finder). Drag the file without transferring focus to finder (click directly on the file and start dragging). This is required for reproducing the issue.
      • The popup opens and has focus but gets no keyboard events. In fact, keyboard events seem to be suppressed for the entire system (including terminal windows).
      • After about 10 seconds, the file-dragging icon reappears from the point it was dropped and scurries back to finder, indicating a rejected drop operation. At this point the keyboard starts functioning normally.
      • Overall, the behavior gives the appearance of hanging on the dropEvent until the system times out and cancels the transaction.

      I am not exec()ing the popup from the dropEvent() handler. Here's the code:

      void MainWindow::dragEnterEvent (QDragEnterEvent* ev)
      {
          ev->acceptProposedAction();
      }
      
      void MainWindow::dropEvent (QDropEvent* ev)
      {
          ev->acceptProposedAction();
          QTimer::singleShot(0, this, SLOT(slot_popup()));
      }
      
      void MainWindow::slot_popup()
      {
          /*
           * This dialog will not be opened in the same iteration
           * of the application event loop that handled the QDropEvent.
           */
          QDialog* dlg = new QDialog(this);
          dlg->setLayout(new QVBoxLayout());
          dlg->layout()->addWidget(new QTextEdit());
          dlg->exec();
      }
      

      If I show() the popup instead of exec() it, then there's no problem. If I make the QTimer 100ms instead of 0 then there's no problem. That suggests to me that there's something buggy about how the EventDispatcher interacts with system drop events on Mac (ie maybe having additional signals on the event queue prevents the dispatcher from returning control back to the OS). Reinforcing this hunch is the following stack trace I get when I break in slot_popup():

      0 MainWindow::slot_popup mainwindow.cpp 37 0x100002f13
      1 MainWindow::qt_static_metacall moc_mainwindow.cpp 49 0x100003eb6
      2 QObject::event 0x100e3c751
      3 QWidget::event 0x1000e9fce
      4 QMainWindow::event 0x10049a4cb
      5 QApplicationPrivate::notify_helper 0x100092bfd
      6 QApplication::notify 0x100099274
      7 QCoreApplication::notifyInternal 0x100e27c8c
      8 QCoreApplicationPrivate::sendPostedEvents 0x100e290a0
      9 _CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION_ 0x7fff85edf6e1
      10 __CFRunLoopDoSources0 0x7fff85edef4d
      11 __CFRunLoopRun 0x7fff85f05d39
      12 CFRunLoopRunSpecific 0x7fff85f05676
      13 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] 0x7fff874e4f9f
      14 -[NSRunLoop(NSRunLoop) runUntilDate:] 0x7fff87568b7a
      15 NSCoreDragReceiveMessageProc 0x7fff8aa2d095
      16 CallReceiveMessageCollectionWithMessage 0x7fff90385243
      17 DoMultipartDropMessage 0x7fff90385348
      18 DoDropMessage 0x7fff90385551
      19 CoreDragMessageHandler 0x7fff9038749d
      20 __CFMessagePortPerform 0x7fff85fc28f9
      21 _CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION_ 0x7fff85ecfcac
      22 __CFRunLoopDoSource1 0x7fff85ecf9db
      23 __CFRunLoopRun 0x7fff85f06117
      24 CFRunLoopRunSpecific 0x7fff85f05676
      25 RunCurrentEventLoopInMode 0x7fff8a1f731f
      26 ReceiveNextEventCommon 0x7fff8a1fe5c9
      27 BlockUntilNextEventMatchingListInMode 0x7fff8a1fe456
      28 _DPSNextEvent 0x7fff8a653f5d
      29 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] 0x7fff8a653861
      30 -[NSApplication run] 0x7fff8a65019d
      31 QEventDispatcherMac::processEvents 0x10004bc80
      32 QEventLoop::processEvents 0x100e26b94
      33 QEventLoop::exec 0x100e26f44
      34 QCoreApplication::exec 0x100e2962c
      35 main main.cpp 10 0x100002c65

      Note specifically the frames with "DropMessage" in them - the dropEvent flow should definitely NOT still be in the stack by the time I get to this function. Moveover, they aren't there if I set the QTimer to larger values (and the problem doesn't manifest).

      NOTE: this works just fine on Windows.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            tpochep Timur Pocheptsov
            wibstr Eric Furze
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes