--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Fri Aug 14 13:59:40 2015 -0500
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Thu Aug 06 17:55:32 2015 +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)
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Fri Aug 14 13:59:40 2015 -0500
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Thu Aug 06 17:55:32 2015 +0300
@@ -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/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Fri Aug 14 13:59:40 2015 -0500
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Thu Aug 06 17:55:32 2015 +0300
@@ -349,6 +349,7 @@
&& [event subtype] == NativeSyncQueueEvent) {
[seenDummyEventLock lockWhenCondition:NO];
[seenDummyEventLock unlockWithCondition:YES];
+
} else if ([event type] == NSApplicationDefined && [event subtype] == ExecuteBlockEvent) {
void (^block)() = (void (^)()) [event data1];
block();
@@ -387,9 +388,7 @@
[pool drain];
}
-
-
-- (void)postDummyEvent {
+- (void)postDummyEvent:(bool)useCocoa {
seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO];
dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime;
@@ -403,19 +402,28 @@
subtype: NativeSyncQueueEvent
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;