From 6293d7427c950ee2011d20fb2fe013438e68ae29 Mon Sep 17 00:00:00 2001 From: Jeff Davidson Date: Thu, 22 Dec 2016 01:23:37 -0800 Subject: [PATCH] Really fix event dispatching in Mac modal event loops Manually dispatching events to eligible windows is error-prone and should really be the responsibility of the system. But the old approach of blocking in nextEventMatchingMask:untilDate:inMode:dequeue seems to fail because while this blocks, events can't even enter the queue. Thus, revert to the old logic, but instead of blocking in nextEventMatchingMask, first block on processing the input source via [NSRunLoop runMode:beforeDate]. This resolves the original problem which was also fixed by the commit 4a83fd4696cd9c238d64a93e834264d5471cf977 but doesn't seem to introduce any regressions, and seems to be a much cleaner fix overall. See #17737. Closes https://github.com/wxWidgets/wxWidgets/pull/365 --- src/osx/cocoa/evtloop.mm | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/osx/cocoa/evtloop.mm b/src/osx/cocoa/evtloop.mm index 12d52c0466..976a973507 100644 --- a/src/osx/cocoa/evtloop.mm +++ b/src/osx/cocoa/evtloop.mm @@ -210,34 +210,23 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout) if ( m_modalSession ) { - NSInteger response = - [NSApp runModalSession:(NSModalSession)m_modalSession]; + NSInteger response = [NSApp runModalSession:(NSModalSession)m_modalSession]; switch (response) { case NSRunContinuesResponse: { - // runModalSession is supposed to handle event dispatching, but - // for some reason we need to dequeue and send events here as - // well (see #17737). - NSEvent *event = [[NSApplication sharedApplication] + [[NSRunLoop currentRunLoop] + runMode:NSDefaultRunLoopMode + beforeDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000.0]]; + if ( [[NSApplication sharedApplication] nextEventMatchingMask: NSAnyEventMask - untilDate: [NSDate dateWithTimeIntervalSinceNow: timeout/1000.0] + untilDate: nil inMode: NSDefaultRunLoopMode - dequeue: YES]; - - if ( event == nil ) - return -1; - - // Only dispatch events for the modal window, or events not - // associated with any window, as other windows should not be - // responsive to inputs when a modal is present. - NSWindow *modalWindow = - m_modalWindow->MacGetTopLevelWindowRef(); - if ( event.window == nil || event.window == modalWindow ) - [NSApp sendEvent: event]; - - return 1; + dequeue: NO] != nil ) + return 1; + + return -1; } case NSRunStoppedResponse: case NSRunAbortedResponse: