Skip to content

Commit

Permalink
8221261: Deadlock on macOS in JFXPanel app when handling IME calls
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinrushforth committed Jan 5, 2024
1 parent ade4074 commit 13c2d01
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ public void run() { synchronized(retString) {

retString[0] = new String(selectedText);
}}
}, fAwtFocussedComponent);
}, fAwtFocussedComponent, true);
} catch (InvocationTargetException ite) { ite.printStackTrace(); }

synchronized(retString) { return retString[0]; }
Expand Down Expand Up @@ -671,7 +671,7 @@ public void run() { synchronized(returnValue) {
returnValue[1] = theIterator.getEndIndex() - theIterator.getBeginIndex();

}}
}, fAwtFocussedComponent);
}, fAwtFocussedComponent, true);
} catch (InvocationTargetException ite) { ite.printStackTrace(); }

synchronized(returnValue) { return returnValue; }
Expand All @@ -696,7 +696,7 @@ public void run() { synchronized(returnValue) {
// insert spot less the length of the composed text.
returnValue[0] = fIMContext.getInsertPositionOffset();
}}
}, fAwtFocussedComponent);
}, fAwtFocussedComponent, true);
} catch (InvocationTargetException ite) { ite.printStackTrace(); }

returnValue[1] = fCurrentTextLength;
Expand Down Expand Up @@ -743,7 +743,7 @@ public void run() { synchronized(rect) {
}
}
}}
}, fAwtFocussedComponent);
}, fAwtFocussedComponent, true);
} catch (InvocationTargetException ite) { ite.printStackTrace(); }

synchronized(rect) { return rect; }
Expand All @@ -763,7 +763,7 @@ public void run() { synchronized(offsetInfo) {
offsetInfo[0] = fIMContext.getLocationOffset(screenX, screenY);
insertPositionOffset[0] = fIMContext.getInsertPositionOffset();
}}
}, fAwtFocussedComponent);
}, fAwtFocussedComponent, true);
} catch (InvocationTargetException ite) { ite.printStackTrace(); }

// This bit of gymnastics ensures that the returned location is within the composed text.
Expand Down
23 changes: 21 additions & 2 deletions src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,25 @@ public T getResult() throws Exception {
*/
public static void invokeAndWait(Runnable runnable, Component component)
throws InvocationTargetException {
invokeAndWait(runnable, component, false);
}

/**
* Package-scope version of invokeAndWait that takes a processEvents
* flag to decide whether to dispatch native events while in the loop.
* Currently, only the IME handlers set processEvents to true. See
* the warning in doAWTRunLoop about using this flag.
*
* Kicks an event over to the appropriate event queue and waits for it to
* finish To avoid deadlocking, we manually run the NSRunLoop while waiting
* Any selector invoked using ThreadUtilities performOnMainThread will be
* processed in doAWTRunLoop The InvocationEvent will call
* LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual
* run loop. Does not dispatch native events while in the loop unless
* the processEvents flag is set to true.
*/
static void invokeAndWait(Runnable runnable, Component component, boolean processEvents)
throws InvocationTargetException {
Objects.requireNonNull(component, "Null component provided to invokeAndWait");

long mediator = createAWTRunLoopMediator();
Expand All @@ -737,7 +756,7 @@ public static void invokeAndWait(Runnable runnable, Component component)
SunToolkit.postEvent(appContext, invocationEvent);
// 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
SunToolkit.flushPendingEvents(appContext);
doAWTRunLoop(mediator, false);
doAWTRunLoop(mediator, processEvents);

checkException(invocationEvent);
}
Expand Down Expand Up @@ -927,7 +946,7 @@ public boolean canPopupOverlapTaskBar() {
* Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent
* by [JNFRunLoop performOnMainThreadWaiting] are processed.
* @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator
* @param processEvents if true - dispatches event while in the nested loop. Used in DnD.
* @param processEvents if true - dispatches event while in the nested loop. Used in DnD and IME.
* Additional attention is needed when using this feature as we short-circuit normal event
* processing which could break Appkit.
* (One known example is when the window is resized with the mouse)
Expand Down

0 comments on commit 13c2d01

Please sign in to comment.