Dequeue and dispatch events in modal event loops

This should be a no-op, as runModalSession's documentation states that
it will handle dispatch event for the modal's window. However, in
practice, it does not seem to be doing so frequently enough for modal
UI to keep up with two-finger scroll events. Dequeuing and manually
dispatching the next event seems to mitigate this.

Note that we only dispatch events that are associated with the modal
dialog's window, or with no window at all, to prevent other windows
from responding to inputs while the modal is present.

Closes #17737

Closes https://github.com/wxWidgets/wxWidgets/pull/365
This commit is contained in:
Jeff Davidson
2016-12-04 08:56:49 -08:00
committed by Vadim Zeitlin
parent cff06eed9d
commit 4a83fd4696

View File

@@ -210,20 +210,34 @@ 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:
{
if ( [[NSApplication sharedApplication]
// 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]
nextEventMatchingMask: NSAnyEventMask
untilDate: [NSDate dateWithTimeIntervalSinceNow: timeout/1000.0]
inMode: NSDefaultRunLoopMode
dequeue: NO] != nil )
return 1;
return -1;
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;
}
case NSRunStoppedResponse:
case NSRunAbortedResponse: