--- old/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m 2015-08-06 17:35:49.000000000 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m 2015-08-06 17:35:49.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,7 @@ return eventCount; } -+ (void) eventCountPlusPlus{ ++ (void) eventCountPlusPlus{ eventCount++; } @@ -167,7 +167,7 @@ ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { setBusy(YES); }); - + CFRunLoopObserverRef notBusyObserver = CFRunLoopObserverCreateWithHandler( NULL, // CFAllocator kCFRunLoopBeforeWaiting, // CFOptionFlags @@ -176,14 +176,14 @@ ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { setBusy(NO); }); - + CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop]; CFRunLoopAddObserver(runLoop, busyObserver, kCFRunLoopDefaultMode); CFRunLoopAddObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode); - + CFRelease(busyObserver); CFRelease(notBusyObserver); - + setBusy(YES); } @@ -344,19 +344,19 @@ // We're either embedded, or showing a splash screen if (isEmbedded) { AWT_STARTUP_LOG(@"running embedded"); - + // We don't track if the runloop is busy, so set it free to let AWT finish when it needs setBusy(NO); } else { AWT_STARTUP_LOG(@"running after showing a splash screen"); } - + // Signal so that JNI_OnLoad can proceed. if (!wasOnMainThread) [AWTStarter appKitIsRunning:nil]; - + // Proceed to exit this call as there is no reason to run the NSApplication event loop. } - + [pool drain]; } @@ -370,24 +370,34 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_nativeSyncQueue (JNIEnv *env, jobject self, jlong timeout) { - int currentEventNum = [AWTToolkit getEventCount]; + long currentEventNum = [AWTToolkit getEventCount]; NSApplication* sharedApp = [NSApplication sharedApplication]; if ([sharedApp isKindOfClass:[NSApplicationAWT class]]) { NSApplicationAWT* theApp = (NSApplicationAWT*)sharedApp; - [theApp postDummyEvent]; - [theApp waitForDummyEvent:timeout]; + // We use two different API to post events to the application, + // - [NSApplication postEvent] + // - CGEventPost(), see CRobot.m + // It was found that if we post an event via CGEventPost in robot and + // immediately after this we will post the second event via + // [NSApp postEvent] then sometimes the second event will be handled + // first. The opposite isn't proved, but we use both here to be safer. + [theApp postDummyEvent:false]; + [theApp waitForDummyEvent:timeout / 2.0]; + [theApp postDummyEvent:true]; + [theApp waitForDummyEvent:timeout / 2.0]; + } else { // could happen if we are embedded inside SWT application, - // in this case just spin a single empty block through + // in this case just spin a single empty block through // the event loop to give it a chance to process pending events [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){}]; } - + if (([AWTToolkit getEventCount] - currentEventNum) != 0) { return JNI_TRUE; } - + return JNI_FALSE; } @@ -516,7 +526,7 @@ beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.010]]; if (processEvents) { //We do not spin a runloop here as date is nil, so does not matter which mode to use - // Processing all events excluding NSApplicationDefined which need to be processed + // Processing all events excluding NSApplicationDefined which need to be processed // on the main loop only (those events are intended for disposing resources) NSEvent *event; if ((event = [NSApp nextEventMatchingMask:(NSAnyEventMask & ~NSApplicationDefined)