Details
-
Bug
-
Resolution: Duplicate
-
P2: Important
-
None
-
5.4.1, 5.5.1
-
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
- relates to
-
QTBUG-59760 Calling QEventLoop::exec(ExcludeUserInput) causes a busy loop with 100% CPU usage on glib
- Closed
-
QTBUG-57101 QFileDialog does not work when run inside an QEventLoop with ExcludeUserInput set
- Closed