changeset 12408:11f7deebf7ae

7124271: [macosx] RealSync test failure Reviewed-by: alexsch, azvegint
author serb
date Sat, 26 Aug 2017 18:28:02 +0100
parents 59f199bb566b
children d3e8d9cf490d
files src/macosx/native/sun/awt/LWCToolkit.m src/macosx/native/sun/osxapp/NSApplicationAWT.h src/macosx/native/sun/osxapp/NSApplicationAWT.m
diffstat 3 files changed, 36 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/native/sun/awt/LWCToolkit.m	Sat Aug 26 14:53:36 2017 +0100
+++ b/src/macosx/native/sun/awt/LWCToolkit.m	Sat Aug 26 18:28:02 2017 +0100
@@ -57,7 +57,7 @@
     return eventCount;
 }
 
-+ (void) eventCountPlusPlus{    
++ (void) eventCountPlusPlus{
     eventCount++;
 }
 
@@ -131,24 +131,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;
 }
 
@@ -323,7 +333,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 & ~NSApplicationDefinedMask)
--- a/src/macosx/native/sun/osxapp/NSApplicationAWT.h	Sat Aug 26 14:53:36 2017 +0100
+++ b/src/macosx/native/sun/osxapp/NSApplicationAWT.h	Sat Aug 26 18:28:02 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, 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
@@ -36,9 +36,9 @@
 - (void) finishLaunching;
 - (void) registerWithProcessManager;
 - (void) setDockIconWithEnv:(JNIEnv *)env;
-- (void) postDummyEvent;
+- (void) postDummyEvent:(bool) useCocoa;
 - (void) postRunnableEvent:(void (^)())block;
-- (void) waitForDummyEvent:(long long) timeout;
+- (void) waitForDummyEvent:(double) timeout;
 
 + (void) runAWTLoopWithApp:(NSApplication*)app;
 
--- a/src/macosx/native/sun/osxapp/NSApplicationAWT.m	Sat Aug 26 14:53:36 2017 +0100
+++ b/src/macosx/native/sun/osxapp/NSApplicationAWT.m	Sat Aug 26 18:28:02 2017 +0100
@@ -377,9 +377,7 @@
     [pool drain];
 }
 
-
-
-- (void)postDummyEvent {
+- (void)postDummyEvent:(bool)useCocoa {
     seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO];
     dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime;
     
@@ -393,19 +391,28 @@
                                          subtype: 0
                                            data1: 0
                                            data2: 0];
-    [NSApp postEvent: event atStart: NO];
+    if (useCocoa) {
+        [NSApp postEvent:event atStart:NO];
+    } else {
+        ProcessSerialNumber psn;
+        GetCurrentProcess(&psn);
+        CGEventPostToPSN(&psn, [event CGEvent]);
+    }
     [pool drain];
 }
 
-- (void)waitForDummyEvent:(long long) timeout {
+- (void)waitForDummyEvent:(double)timeout {
+    bool unlock = true;
     if (timeout >= 0) {
-        double sec = ((double) timeout)/1000;
-        [seenDummyEventLock lockWhenCondition:YES
+        double sec = timeout / 1000;
+        unlock = [seenDummyEventLock lockWhenCondition:YES
                                beforeDate:[NSDate dateWithTimeIntervalSinceNow:sec]];
     } else {
         [seenDummyEventLock lockWhenCondition:YES];
     }
-    [seenDummyEventLock unlock];
+    if (unlock) {
+        [seenDummyEventLock unlock];
+    }
     [seenDummyEventLock release];
 
     seenDummyEventLock = nil;