# HG changeset patch # User kcr # Date 1409180659 25200 # Node ID af49047439dcbef9f11eced17189c75383625dae # Parent a3db655c8a6c92c46fe1b6be5e1629b6ea13e245 RT-38289: [Quantum] Control ActionEvent is fired on Stage closing and the App hangs if modal window is then shown diff --git a/modules/graphics/src/main/java/com/sun/glass/ui/Accessible.java b/modules/graphics/src/main/java/com/sun/glass/ui/Accessible.java --- a/modules/graphics/src/main/java/com/sun/glass/ui/Accessible.java +++ b/modules/graphics/src/main/java/com/sun/glass/ui/Accessible.java @@ -32,6 +32,8 @@ import java.security.PrivilegedAction; import com.sun.javafx.scene.NodeHelper; import com.sun.javafx.scene.SceneHelper; +import com.sun.javafx.tk.quantum.QuantumToolkit; +import java.util.concurrent.locks.ReentrantLock; import javafx.scene.AccessibleAction; import javafx.scene.AccessibleAttribute; import javafx.scene.AccessibleRole; @@ -154,9 +156,21 @@ private GetAttribute getAttribute = new GetAttribute(); public Object getAttribute(AccessibleAttribute attribute, Object... parameters) { - getAttribute.attribute = attribute; - getAttribute.parameters = parameters; - return AccessController.doPrivileged(getAttribute, getAccessControlContext()); + final ReentrantLock renderLock = QuantumToolkit.getRenderLock(); + final boolean locked = renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("getAttribute: renderLock held!"); + renderLock.unlock(); + } + try { + getAttribute.attribute = attribute; + getAttribute.parameters = parameters; + return AccessController.doPrivileged(getAttribute, getAccessControlContext()); + } finally { + if (locked) { + renderLock.lock(); + } + } } private class ExecuteAction implements PrivilegedAction { @@ -171,9 +185,21 @@ private ExecuteAction executeAction = new ExecuteAction(); public void executeAction(AccessibleAction action, Object... parameters) { - executeAction.action = action; - executeAction.parameters = parameters; - AccessController.doPrivileged(executeAction, getAccessControlContext()); + final ReentrantLock renderLock = QuantumToolkit.getRenderLock(); + final boolean locked = renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("executeAction: renderLock held!"); + renderLock.unlock(); + } + try { + executeAction.action = action; + executeAction.parameters = parameters; + AccessController.doPrivileged(executeAction, getAccessControlContext()); + } finally { + if (locked) { + renderLock.lock(); + } + } } public abstract void sendNotification(AccessibleAttribute notification); diff --git a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java --- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java +++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java @@ -224,7 +224,18 @@ keyNotification.chars = chars; keyNotification.modifiers = modifiers; - AccessController.doPrivileged(keyNotification, scene.getAccessControlContext()); + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleKeyEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } + try { + AccessController.doPrivileged(keyNotification, scene.getAccessControlContext()); + } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } + } } private static EventType mouseEventType(int glassType) { @@ -362,6 +373,17 @@ } } + private String mouseEventTypeToString(int type) { + switch (type) { + case MouseEvent.MOVE: return "MouseEvent.MOVE"; + case MouseEvent.UP: return "MouseEvent.UP"; + case MouseEvent.DOWN: return "MouseEvent.DOWN"; + case MouseEvent.ENTER: return "MouseEvent.ENTER"; + case MouseEvent.EXIT: return "MouseEvent.EXIT"; + } + return "unknown [" + type + "]"; + } + @Override public void handleMouseEvent(View view, long time, int type, int button, int x, int y, int xAbs, int yAbs, @@ -379,7 +401,21 @@ mouseNotification.isPopupTrigger = isPopupTrigger; mouseNotification.isSynthesized = isSynthesized; - AccessController.doPrivileged(mouseNotification, scene.getAccessControlContext()); + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + if (type != MouseEvent.EXIT) { +// Thread.dumpStack(); + System.err.println("handleMouseEvent(" + mouseEventTypeToString(type) + "): renderLock held!"); + } + ViewPainter.renderLock.unlock(); + } + try { + AccessController.doPrivileged(mouseNotification, scene.getAccessControlContext()); + } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } + } } @Override public void handleMenuEvent(final View view, @@ -389,6 +425,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("MENU_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleMenuEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -404,6 +445,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -420,6 +464,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("SCROLL_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleScrollEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -446,6 +495,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -527,6 +579,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("INPUT_METHOD_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleInputMethodEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -548,6 +605,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -615,12 +675,20 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("DRAG_ENTER"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleDragEnter: renderLock held!"); + ViewPainter.renderLock.unlock(); + } TransferMode action; try { action = dndHandler.handleDragEnter(x, y, xAbs, yAbs, actionToTransferMode(recommendedDropAction), dropTargetAssistant); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -632,9 +700,17 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("DRAG_LEAVE"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleDragLeave: renderLock held!"); + ViewPainter.renderLock.unlock(); + } try { dndHandler.handleDragLeave(dropTargetAssistant); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -649,12 +725,20 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("DRAG_DROP"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleDragDrop: renderLock held!"); + ViewPainter.renderLock.unlock(); + } TransferMode action; try { action = dndHandler.handleDragDrop(x, y, xAbs, yAbs, actionToTransferMode(recommendedDropAction), dropTargetAssistant); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -670,12 +754,20 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("DRAG_OVER"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleDragOver: renderLock held!"); + ViewPainter.renderLock.unlock(); + } TransferMode action; try { action = dndHandler.handleDragOver(x, y, xAbs, yAbs, actionToTransferMode(recommendedDropAction), dropTargetAssistant); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -692,10 +784,18 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("DRAG_START"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleDragStart: renderLock held!"); + ViewPainter.renderLock.unlock(); + } dropSourceAssistant = assistant; try { dndHandler.handleDragStart(button, x, y, xAbs, yAbs, assistant); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -706,9 +806,17 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("DRAG_END"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleDragEnd: renderLock held!"); + ViewPainter.renderLock.unlock(); + } try { dndHandler.handleDragEnd(actionToTransferMode(performedAction), dropSourceAssistant); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -787,6 +895,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("VIEW_EVENT: "+ViewEvent.getTypeString(type)); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { +// System.err.println("handleViewEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } viewNotification.view = view; viewNotification.time = time; viewNotification.type = type; @@ -794,6 +907,9 @@ AccessController.doPrivileged(viewNotification, scene.getAccessControlContext()); } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -809,6 +925,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("SCROLL_GESTURE_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleScrollGestureEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -850,6 +971,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -867,6 +991,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("ZOOM_GESTURE_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleZoomGestureEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -905,6 +1034,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -921,6 +1053,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("ROTATE_GESTURE_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleRotateGestureEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -959,6 +1096,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -974,6 +1114,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("SWIPE_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleSwipeGestureEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -1015,6 +1160,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -1028,6 +1176,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("BEGIN_TOUCH_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleBeginTouchEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -1048,6 +1201,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -1063,6 +1219,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("NEXT_TOUCH_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleNextTouchEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -1095,6 +1256,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } @@ -1107,6 +1271,11 @@ if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput("END_TOUCH_EVENT"); } + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleEndTouchEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } WindowStage stage = scene.getWindowStage(); try { if (stage != null) { @@ -1122,6 +1291,9 @@ if (stage != null) { stage.setInEventHandler(false); } + if (locked) { + ViewPainter.renderLock.lock(); + } if (PULSE_LOGGING_ENABLED) { PulseLogger.newInput(null); } diff --git a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassWindowEventHandler.java b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassWindowEventHandler.java --- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassWindowEventHandler.java +++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassWindowEventHandler.java @@ -121,11 +121,22 @@ @Override public void handleLevelEvent(int level) { - AccessControlContext acc = stage.getAccessControlContext(); - AccessController.doPrivileged((PrivilegedAction)() -> { - stage.stageListener.changedAlwaysOnTop(level != Level.NORMAL); - return (Void)null; - } , acc); + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleLevelEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } + try { + AccessControlContext acc = stage.getAccessControlContext(); + AccessController.doPrivileged((PrivilegedAction)() -> { + stage.stageListener.changedAlwaysOnTop(level != Level.NORMAL); + return (Void)null; + } , acc); + } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } + } } @Override @@ -133,8 +144,19 @@ this.window = window; this.type = type; - AccessControlContext acc = stage.getAccessControlContext(); - AccessController.doPrivileged(this, acc); + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { +// System.err.println("handleWindowEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } + try { + AccessControlContext acc = stage.getAccessControlContext(); + AccessController.doPrivileged(this, acc); + } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } + } } @Override @@ -150,10 +172,21 @@ } } - AccessControlContext acc = stage.getAccessControlContext(); - AccessController.doPrivileged((PrivilegedAction)() -> { - stage.stageListener.changedScreen(oldScreen, newScreen); - return (Void)null; - } , acc); + final boolean locked = ViewPainter.renderLock.isHeldByCurrentThread(); + if (locked) { + System.err.println("handleScreenChangedEvent: renderLock held!"); + ViewPainter.renderLock.unlock(); + } + try { + AccessControlContext acc = stage.getAccessControlContext(); + AccessController.doPrivileged((PrivilegedAction)() -> { + stage.stageListener.changedScreen(oldScreen, newScreen); + return (Void)null; + } , acc); + } finally { + if (locked) { + ViewPainter.renderLock.lock(); + } + } } } diff --git a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java --- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java +++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java @@ -72,6 +72,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReentrantLock; import com.sun.glass.ui.Application; import com.sun.glass.ui.Clipboard; import com.sun.glass.ui.ClipboardAssistance; @@ -351,6 +352,11 @@ } } + // Called by glass Accessible to get the renderLock + public static ReentrantLock getRenderLock() { + return ViewPainter.renderLock; + } + boolean hasNativeSystemVsync() { return nativeSystemVsync; }