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

Native Gtk2 file dialog (and possibly any other native dialog) can come up in a broken state when opened after a QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents) call.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P2: Important
    • None
    • 5.4.1, 5.5.1
    • QPA: X11/XCB
    • None

    Description

      When calling 'qApp->processEvents(QEventLoop::ExcludeUserInputEvents, ...);', the Glib event dispatcher will execute the following code:

      bool QPAEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
      {
          m_flags = flags;
          return QEventDispatcherGlib::processEvents(m_flags);
      }
      

      Which is in charge of setting m_flags, which will have to be later used, in:

      #0  QT::userEventSourceDispatch (source=0x857f0a8) at eventdispatchers/qeventdispatcher_glib.cpp:68                                       // <------------------ uses m_flags
      #1  0xf66626d3 in g_main_context_dispatch () from /lib/i386-linux-gnu/libglib-2.0.so.0
      #2  0xf6662a70 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
      #3  0xf6662b51 in g_main_context_iteration () from /lib/i386-linux-gnu/libglib-2.0.so.0
      #4  0xf6db9a78 in QT::QEventDispatcherGlib::processEvents (this=0x857ee98, flags=...) at kernel/qeventdispatcher_glib.cpp:418
      #5  0xf61e04e9 in QT::QPAEventDispatcherGlib::processEvents (this=0x857ee98, flags=...) at eventdispatchers/qeventdispatcher_glib.cpp:116 // <------------------ sets m_flags
      #6  0xf6d3d7f2 in QT::QCoreApplication::processEvents (flags=..., maxtime=1000) at kernel/qcoreapplication.cpp:1133
      (...)
      

      It all looks fine, but...

      Conceptually, it means the 'QPAEventDispatcherGlib' instance will always be left containing the flags that were set by the last call to processEvents().
      And that is a problem when opening a native dialog, because the same 'userEventSourceDispatch' callback will be called, and re-use the last m_flags value.

      Here's what happens when a QFileDialog::getOpenFileName() is issued:

      #0  QT::QWindowSystemInterface::sendWindowSystemEvents (flags=...) at kernel/qwindowsysteminterface.cpp:562
      #1  0xf61e00db in QT::userEventSourceDispatch (source=0x857f0a8) at eventdispatchers/qeventdispatcher_glib.cpp:70
      #2  0xf66626d3 in g_main_context_dispatch () from /lib/i386-linux-gnu/libglib-2.0.so.0
      #3  0xf6662a70 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
      #4  0xf6662ecb in g_main_loop_run () from /lib/i386-linux-gnu/libglib-2.0.so.0
      #5  0xf5302e08 in gtk_dialog_run () from /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0
      #6  0xf610bd51 in QT::QGtk2Dialog::exec (this=0x8fba268) at qgtk2dialoghelpers.cpp:98
      #7  0xf610d0f6 in QT::QGtk2FileDialogHelper::exec (this=0x8ea4408) at qgtk2dialoghelpers.cpp:260
      #8  0xf7925fe8 in QT::QDialog::exec (this=0xffff91a8) at dialogs/qdialog.cpp:537
      #9  0xf7932a1e in QT::QFileDialog::getOpenFileUrl (...)
      #10 0xf79328b6 in QT::QFileDialog::getOpenFileName (...)
      (...)
      

      Now, if that QFileDialog::getOpenFileName() is issued after a QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents) call (and if nobody in the meantime called processEvents() and thus had a chance to re-set the 'm_flags' variable), then Qt will keep processing only non-user-input events (i.e., 'flags' at frame #0 in the above stack trace will be == 1), while showing the native dialog, which will make the dialog appear frozen (see attached screenshot.)

      I could reproduce this problem on a wide variety of linux boxes.

      Attached, you will find:

      • a screenshot of the frozen file dialog. (note: sometimes some parts of the dialog (i.e., the left-hand side) get shown (as in the attached picture), and sometimes the whole dialog looks entirely grey)
      • a tiny testcase to reproduce
      • and finally a simple suggested patch, that works for me, and hopefully doesn't break anything

      What do you think?

      Note: I could also reproduce the problem with Qt 5.5.1, and AFAICT it can be reproduced with the trunk, since the QPAEventDispatcherGlib::processEvents() code is still the same.

      Attachments

        Issue Links

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

          Activity

            People

              paeglis Gatis Paeglis
              aundro Arnaud Diederen
              Votes:
              2 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes