Cocoa: fix unresponsive dialogs causes application to hang

The reason for this bug seems to be related to how we wait for
more events in the event dispatcher. We use the nextEventMatchingMask
function, which already in Qt4 showed to have problems when telling
it to not dequeue the event. The solution back then was to
tell it to dequeue the event, and instead repost in front again.
Why this was changed in Qt5 is uncertain (other than it being tempting)
but moving the same code back in will solve the bug.

Note that this bug might also stem from the fact that the run loop
sources we add in the event dispatcher fires before the application
is really ready to show modal dialogs. E.g refusing to execute a
modal dialog before NSAppDelegate applicationWillFinishLaunching
is called will also fix the problem. But this code change is to big
atm, and can easily introduce other unforeseen regressions.

Task-number: QTBUG-28283
Change-Id: I07cd109568c2b9c782cf5120a9eb2ac71128cada
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
This commit is contained in:
Richard Moe Gustavsen 2012-12-05 11:36:25 +01:00 committed by The Qt Project
parent fd1f65a9b8
commit fd4106e2d1

View File

@ -510,14 +510,16 @@ static bool IsMouseOrKeyEvent( NSEvent* event )
static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRunLoopMode)
{
// If no event exist in the cocoa event que, wait
// (and free up cpu time) until at least one event occur.
// This implementation is a bit on the edge, but seems to
// work fine:
[NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:runLoopMode
dequeue:NO];
// If no event exist in the cocoa event que, wait (and free up cpu time) until
// at least one event occur. Setting 'dequeuing' to 'no' in the following call
// causes it to hang under certain circumstances (QTBUG-28283), so we tell it
// to dequeue instead, just to repost the event again:
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:runLoopMode
dequeue:YES];
if (event)
[NSApp postEvent:event atStart:YES];
}
bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)