Compare commits

..

2 Commits
1620 ... 1584

Author SHA1 Message Date
Dmitry Batrak
dec27719cf JBR-3640 java/awt/Modal/ModalFocusTransferTests/FocusTransferDWFAppModalTest.java: window Open button lost focus when it should not
(cherry picked from commit a7d486ca3d)
2021-08-04 13:34:49 +07:00
Artem Bochkarev
c4fb2e5e55 JBR-3342: add npe check
fixed JBR-3342 SIGILL at [libsystem_kernel] __kill NPE/OOME at java.desktop/sun.lwawt.LWComponentPeer.windowToLocal / -[NSApplication(JCEFApplication) _swizzled_sendEvent:]

(cherry picked from commit 37e6e8e616)
2021-08-04 13:34:41 +07:00
13 changed files with 221 additions and 853 deletions

View File

@@ -934,7 +934,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
getTarget(), lightweightChild, temporary,
focusedWindowChangeAllowed, time, cause, true);
focusedWindowChangeAllowed, time, cause, false);
switch (result) {
case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
return false;
@@ -968,22 +968,15 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return false;
}
boolean res = parentPeer.requestWindowFocus(cause);
// If parent window can be made focused and has been made focused (synchronously)
// then we can proceed with children, otherwise we retreat
if (!res || !parentWindow.isFocused()) {
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
focusLog.fine("request rejected, res= " + res + ", parentWindow.isFocused()=" +
parentWindow.isFocused());
}
return parentPeer.requestWindowFocus(cause, () -> {
LWKeyboardFocusManagerPeer.removeLastFocusRequest(getTarget());
return false;
}
}, () -> {
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
Component focusOwner = kfmPeer.getCurrentFocusOwner();
return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
getTarget(), true, cause, focusOwner);
Component focusOwner = kfmPeer.getCurrentFocusOwner();
LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
getTarget(), false, cause, focusOwner);
});
case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
return true;

View File

@@ -61,18 +61,18 @@ public class LWLightweightFramePeer extends LWWindowPeer implements OverrideNati
}
@Override
public boolean requestWindowFocus(FocusEvent.Cause cause) {
public boolean requestWindowFocus(FocusEvent.Cause cause, Runnable r, Runnable lightweightRequest) {
if (!focusAllowedFor()) {
return false;
}
if (getPlatformWindow().rejectFocusRequest(cause)) {
/*if (getPlatformWindow().rejectFocusRequest(cause)) {
return false;
}
}*/
Window opposite = LWKeyboardFocusManagerPeer.getInstance().
getCurrentFocusedWindow();
changeFocusedWindow(true, opposite);
changeFocusedWindow(true, opposite, () -> {});
return true;
}

View File

@@ -284,6 +284,33 @@ public class LWWindowPeer
super.setVisibleImpl(visible);
// TODO: update graphicsConfig, see 4868278
platformWindow.setVisible(visible);
if (isSimpleWindow()) {
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
if (visible) {
if (!getTarget().isAutoRequestFocus()) {
return;
} else {
requestWindowFocus(FocusEvent.Cause.ACTIVATION, () -> {}, () -> {});
}
// Focus the owner in case this window is focused.
} else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
// Transfer focus to the owner.
Window targetOwner = LWWindowPeer.this.getTarget().getOwner();
while (targetOwner != null && (targetOwner.getOwner() != null && !targetOwner.isFocusableWindow())) {
targetOwner = targetOwner.getOwner();
}
if (targetOwner != null) {
LWWindowPeer owner = (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(targetOwner);
if (owner != null) {
owner.requestWindowFocus(FocusEvent.Cause.ACTIVATION, () -> {}, () -> {});
}
}
}
}
}
@Override
@@ -758,7 +785,7 @@ public class LWWindowPeer
@Override
public void notifyActivation(boolean activation, LWWindowPeer opposite) {
Window oppositeWindow = (opposite == null)? null : opposite.getTarget();
changeFocusedWindow(activation, oppositeWindow);
changeFocusedWindow(activation, oppositeWindow, () -> {});
}
// MouseDown in non-client area
@@ -875,7 +902,7 @@ public class LWWindowPeer
// 2. An active but not focused owner frame/dialog is clicked.
// The mouse event then will trigger a focus request "in window" to the component, so the window
// should gain focus before.
requestWindowFocus(FocusEvent.Cause.MOUSE_EVENT);
requestWindowFocus(FocusEvent.Cause.MOUSE_EVENT, () -> {}, () -> {});
mouseDownTarget[targetIdx] = targetPeer;
} else if (id == MouseEvent.MOUSE_DRAGGED) {
@@ -1231,17 +1258,19 @@ public class LWWindowPeer
* Requests platform to set native focus on a frame/dialog.
* In case of a simple window, triggers appropriate java focus change.
*/
public boolean requestWindowFocus(FocusEvent.Cause cause) {
public boolean requestWindowFocus(FocusEvent.Cause cause, Runnable rejectFocusRequest, Runnable lightweightRequest) {
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
focusLog.fine("requesting native focus to " + this);
}
if (!focusAllowedFor()) {
focusLog.fine("focus is not allowed");
rejectFocusRequest.run();
return false;
}
if (platformWindow.rejectFocusRequest(cause)) {
rejectFocusRequest.run();
return false;
}
@@ -1256,13 +1285,19 @@ public class LWWindowPeer
// In case the toplevel is active but not focused, change focus directly,
// as requesting native focus on it will not have effect.
if (getTarget() == currentActive && !getTarget().hasFocus()) {
changeFocusedWindow(true, opposite);
if (getTarget() == currentActive && !getTarget().isFocused()) {
changeFocusedWindow(true, opposite, lightweightRequest);
return true;
}
return platformWindow.requestWindowFocus();
focusLog.fine("platformWindow.requestWindowFocus()");
boolean requestFocusResult = platformWindow.requestWindowFocus();
if (requestFocusResult) {
lightweightRequest.run();
return true;
}
return false;
}
protected boolean focusAllowedFor() {
@@ -1290,7 +1325,7 @@ public class LWWindowPeer
@Override
public void emulateActivation(boolean activate) {
changeFocusedWindow(activate, null);
changeFocusedWindow(activate, null, () -> {});
}
@SuppressWarnings("deprecation")
@@ -1309,7 +1344,7 @@ public class LWWindowPeer
/*
* Changes focused window on java level.
*/
protected void changeFocusedWindow(boolean becomesFocused, Window opposite) {
protected void changeFocusedWindow(boolean becomesFocused, Window opposite, Runnable lightweightRequestRunnable) {
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
}
@@ -1348,19 +1383,22 @@ public class LWWindowPeer
}
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
if (!becomesFocused && kfmPeer.getCurrentFocusedWindow() != getTarget()) {
// late window focus lost event - ingoring
return;
}
kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, opposite, System.currentTimeMillis());
SunToolkit.setSystemGenerated(windowEvent);
AWTAccessor.getAWTEventAccessor().setPosted(windowEvent);
PeerEvent pe = new PeerEvent(getTarget(), () -> {
((Component)windowEvent.getSource()).dispatchEvent(windowEvent);
if (becomesFocused) {
lightweightRequestRunnable.run();
}
}, PeerEvent.ULTIMATE_PRIORITY_EVENT);
// TODO: wrap in SequencedEvent
SunToolkit.postPriorityEvent(windowEvent);
postEvent(pe);
}
/*
@@ -1481,4 +1519,4 @@ public class LWWindowPeer
}
return handle[0];
}
}
}

View File

@@ -105,7 +105,7 @@ class CAccessibility implements PropertyChangeListener {
static <T> T invokeAndWait(final Callable<T> callable, final Component c, final T defValue) {
T value = null;
try {
value = LWCToolkit.invokeAndWait(callable, c, INVOKE_TIMEOUT_SECONDS);
value = EventQueue.isDispatchThread() ? callable.call() : LWCToolkit.invokeAndWait(callable, c, INVOKE_TIMEOUT_SECONDS);
} catch (final Exception e) { e.printStackTrace(); }
return value != null ? value : defValue;
@@ -603,132 +603,87 @@ class CAccessibility implements PropertyChangeListener {
if (a == null) return null;
return invokeAndWait(new Callable<Object[]>() {
public Object[] call() throws Exception {
return getChildrenAndRolesImpl(a, c, whichChildren, allowIgnored);
ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
_addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
/* In the case of fetching a selection, need to check to see if
* the active descendant is at the beginning of the list. If it
* is not it needs to be moved to the beginning of the list so
* VoiceOver will annouce it correctly. The list returned
* from Java is always in order from top to bottom, but when shift
* selecting downward (extending the list) or multi-selecting using
* the VO keys control+option+command+return the active descendant
* is not at the top of the list in the shift select down case and
* may not be in the multi select case.
*/
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
if (!childrenAndRoles.isEmpty()) {
AccessibleContext activeDescendantAC =
CAccessible.getActiveDescendant(a);
if (activeDescendantAC != null) {
String activeDescendantName =
activeDescendantAC.getAccessibleName();
AccessibleRole activeDescendantRole =
activeDescendantAC.getAccessibleRole();
// Move active descendant to front of list.
// List contains pairs of each selected item's
// Accessible and AccessibleRole.
ArrayList<Object> newArray = new ArrayList<Object>();
int count = childrenAndRoles.size();
Accessible currentAccessible = null;
AccessibleContext currentAC = null;
String currentName = null;
AccessibleRole currentRole = null;
for (int i = 0; i < count; i+=2) {
// Is this the active descendant?
currentAccessible = (Accessible)childrenAndRoles.get(i);
currentAC = currentAccessible.getAccessibleContext();
currentName = currentAC.getAccessibleName();
currentRole = (AccessibleRole)childrenAndRoles.get(i+1);
if ( currentName.equals(activeDescendantName) &&
currentRole.equals(activeDescendantRole) ) {
newArray.add(0, currentAccessible);
newArray.add(1, currentRole);
} else {
newArray.add(currentAccessible);
newArray.add(currentRole);
}
}
childrenAndRoles = newArray;
}
}
}
if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
return childrenAndRoles.toArray();
}
return new Object[] { childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1) };
}
}, c);
}
private static Object[] getChildrenAndRolesImpl(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored) {
if (a == null) return null;
ArrayList<Object> childrenAndRoles = new ArrayList<Object>();
_addChildren(a, whichChildren, allowIgnored, childrenAndRoles);
/* In case of fetching a selection, we need to check if
* the active descendant is at the beginning of the list, or
* otherwise move it, so that VoiceOver announces it correctly.
* The java list is always in order from top to bottom, but when
* (1) shift-selecting downward (extending the list) or (2) multi-selecting with
* the VO keys (CTRL+ALT+CMD+RETURN) the active descendant
* is not at the top of the list in the 1st case and may not be in the 2nd.
*/
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
if (!childrenAndRoles.isEmpty()) {
AccessibleContext activeDescendantAC =
CAccessible.getActiveDescendant(a);
if (activeDescendantAC != null) {
String activeDescendantName =
activeDescendantAC.getAccessibleName();
AccessibleRole activeDescendantRole =
activeDescendantAC.getAccessibleRole();
// Move active descendant to front of list.
// List contains pairs of each selected item's
// Accessible and AccessibleRole.
ArrayList<Object> newArray = new ArrayList<Object>();
int count = childrenAndRoles.size();
Accessible currentAccessible = null;
AccessibleContext currentAC = null;
String currentName = null;
AccessibleRole currentRole = null;
for (int i = 0; i < count; i += 2) {
// Is this the active descendant?
currentAccessible = (Accessible) childrenAndRoles.get(i);
currentAC = currentAccessible.getAccessibleContext();
currentName = currentAC.getAccessibleName();
currentRole = (AccessibleRole) childrenAndRoles.get(i + 1);
if (currentName != null && currentName.equals(activeDescendantName) &&
currentRole.equals(activeDescendantRole)) {
newArray.add(0, currentAccessible);
newArray.add(1, currentRole);
} else {
newArray.add(currentAccessible);
newArray.add(currentRole);
}
}
childrenAndRoles = newArray;
}
}
}
if ((whichChildren < 0) || (whichChildren * 2 >= childrenAndRoles.size())) {
return childrenAndRoles.toArray();
}
return new Object[]{childrenAndRoles.get(whichChildren * 2), childrenAndRoles.get((whichChildren * 2) + 1)};
}
// This method is called from the native
// Each child takes up three entries in the array: one for itself, one for its role, and one for the recursion level
private static Object[] getChildrenAndRolesRecursive(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored, final int level) {
public static Object[] getChildrenAndRolesRecursive(final Accessible a, final Component c, final int whichChildren, final boolean allowIgnored, final int level) {
if (a == null) return null;
return invokeAndWait(new Callable<Object[]>() {
public Object[] call() throws Exception {
ArrayList<Object> currentLevelChildren = new ArrayList<Object>();
currentLevelChildren.addAll(Arrays.asList(getChildrenAndRoles(a, c, JAVA_AX_ALL_CHILDREN, allowIgnored)));
ArrayList<Object> allChildren = new ArrayList<Object>();
ArrayList<Accessible> parentStack = new ArrayList<Accessible>();
parentStack.add(a);
ArrayList<Integer> indexses = new ArrayList<Integer>();
Integer index = 0;
int currentLevel = level;
while (!parentStack.isEmpty()) {
Accessible p = parentStack.get(parentStack.size() - 1);
currentLevelChildren.addAll(Arrays.asList(getChildrenAndRolesImpl(p, c, JAVA_AX_ALL_CHILDREN, allowIgnored)));
if ((currentLevelChildren.size() == 0) || (index >= currentLevelChildren.size())) {
if (!parentStack.isEmpty()) parentStack.remove(parentStack.size() - 1);
if (!indexses.isEmpty()) index = indexses.remove(indexses.size() - 1);
currentLevel -= 1;
currentLevelChildren.clear();
continue;
}
Accessible ca = null;
Object obj = currentLevelChildren.get(index);
if (!(obj instanceof Accessible)) {
index += 2;
currentLevelChildren.clear();
continue;
}
ca = (Accessible) obj;
Object role = currentLevelChildren.get(index + 1);
currentLevelChildren.clear();
AccessibleContext cac = ca.getAccessibleContext();
if (cac == null) {
index += 2;
continue;
}
if ((cac.getAccessibleStateSet().contains(AccessibleState.SELECTED) && (whichChildren == JAVA_AX_SELECTED_CHILDREN)) ||
(cac.getAccessibleStateSet().contains(AccessibleState.VISIBLE) && (whichChildren == JAVA_AX_VISIBLE_CHILDREN)) ||
for (int i = 0; i < currentLevelChildren.size(); i += 2) {
if ((((Accessible) currentLevelChildren.get(i)).getAccessibleContext().getAccessibleStateSet().contains(AccessibleState.SELECTED) && (whichChildren == JAVA_AX_SELECTED_CHILDREN)) ||
(((Accessible) currentLevelChildren.get(i)).getAccessibleContext().getAccessibleStateSet().contains(AccessibleState.VISIBLE) && (whichChildren == JAVA_AX_VISIBLE_CHILDREN)) ||
(whichChildren == JAVA_AX_ALL_CHILDREN)) {
allChildren.add(ca);
allChildren.add(role);
allChildren.add(String.valueOf(currentLevel));
allChildren.add(currentLevelChildren.get(i));
allChildren.add(currentLevelChildren.get(i + 1));
allChildren.add(String.valueOf(level));
}
index += 2;
if (cac.getAccessibleStateSet().contains(AccessibleState.EXPANDED)) {
parentStack.add(ca);
indexses.add(index);
index = 0;
currentLevel += 1;
continue;
if (getAccessibleStateSet(((Accessible) currentLevelChildren.get(i)).getAccessibleContext(), c).contains(AccessibleState.EXPANDED)) {
allChildren.addAll(Arrays.asList(getChildrenAndRolesRecursive(((Accessible) currentLevelChildren.get(i)), c, whichChildren, allowIgnored, level + 1)));
}
}
return allChildren.toArray();
}
}, c);

View File

@@ -96,7 +96,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native void nativeSetNSWindowMinMax(long nsWindowPtr, double minW, double minH, double maxW, double maxH);
private static native void nativePushNSWindowToBack(long nsWindowPtr);
private static native void nativePushNSWindowToFront(long nsWindowPtr, boolean wait);
private static native void nativeHideWindow(long nsWindowPtr, boolean wait);
private static native void nativeSetNSWindowTitle(long nsWindowPtr, String title);
private static native void nativeRevalidateNSWindowShadow(long nsWindowPtr);
private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
@@ -761,9 +760,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Actually show or hide the window
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
if (!visible) {
execute(ptr -> AWTThreading.executeWaitToolkit(wait -> nativeHideWindow(ptr, wait)));
} else if (delayShowing()) {
if (visible && delayShowing()) {
if (blocker == null) {
Window focusedWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
LWWindowPeer focusedWindowBlocker = getBlockerFor(focusedWindow);
@@ -773,34 +770,43 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
owner.execute(CWrapper.NSWindow::orderFront);
}
}
} else if (blocker == null) {
} else if (blocker == null || !visible) {
// If it ain't blocked, or is being hidden, go regular way
boolean isPopup = (target.getType() == Window.Type.POPUP);
execute(ptr -> {
if (visible) {
boolean isPopup = (target.getType() == Window.Type.POPUP);
execute(ptr -> {
boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(ptr);
if (!isKeyWindow) {
logger.fine("setVisible: makeKeyAndOrderFront");
CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
} else {
logger.fine("setVisible: orderFront");
CWrapper.NSWindow.orderFront(ptr);
}
if (owner != null
&& owner.getPeer() instanceof LWLightweightFramePeer) {
LWLightweightFramePeer peer =
(LWLightweightFramePeer) owner.getPeer();
long ownerWindowPtr = peer.getOverriddenWindowHandle();
if (ownerWindowPtr != 0) {
//Place window above JavaFX stage
CWrapper.NSWindow.addChildWindow(
ownerWindowPtr, ptr,
CWrapper.NSWindow.NSWindowAbove);
boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(ptr);
if (!isKeyWindow) {
logger.fine("setVisible: makeKeyAndOrderFront");
CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
} else {
logger.fine("setVisible: orderFront");
CWrapper.NSWindow.orderFront(ptr);
}
}
});
if (owner != null
&& owner.getPeer() instanceof LWLightweightFramePeer) {
LWLightweightFramePeer peer =
(LWLightweightFramePeer) owner.getPeer();
long ownerWindowPtr = peer.getOverriddenWindowHandle();
if (ownerWindowPtr != 0) {
//Place window above JavaFX stage
CWrapper.NSWindow.addChildWindow(
ownerWindowPtr, ptr,
CWrapper.NSWindow.NSWindowAbove);
}
}
});
} else {
execute(ptr->{
// immediately hide the window
CWrapper.NSWindow.orderOut(ptr);
// process the close
CWrapper.NSWindow.close(ptr);
});
}
} else {
// otherwise, put it in a proper z-order
CPlatformWindow bw

View File

@@ -622,7 +622,7 @@ AWT_ASSERT_APPKIT_THREAD;
AWT_ASSERT_APPKIT_THREAD;
for (NSWindow* window in [NSApp windows]) {
if (window.onActiveSpace && window.mainWindow && [AWTWindow isJavaPlatformWindowVisible:window]) {
if (window.onActiveSpace && [AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
// there can be only one current blocker per window hierarchy,
// so we're checking just hierarchy root
@@ -635,24 +635,6 @@ AWT_ASSERT_APPKIT_THREAD;
}
}
- (void) processVisibleChildren:(void(^)(AWTWindow*))action {
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
NSWindow *window;
while ((window = [windowEnumerator nextObject]) != nil) {
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
AWTWindow *parent = awtWindow.ownerWindow;
while (parent != nil) {
if (parent == self) {
action(awtWindow);
break;
}
parent = parent.ownerWindow;
}
}
}
}
// Orders window's childs based on the current focus state
- (void) orderChildWindows:(BOOL)focus {
AWT_ASSERT_APPKIT_THREAD;
@@ -662,28 +644,39 @@ AWT_ASSERT_APPKIT_THREAD;
return;
}
[self processVisibleChildren:^void(AWTWindow* child){
// Do not order 'always on top' windows
if (!IS(child.styleBits, ALWAYS_ON_TOP)) {
NSWindow *window = child.nsWindow;
NSWindow *owner = child.ownerWindow.nsWindow;
if (focus) {
// Move the childWindow to floating level
// so it will appear in front of its
// parent which owns the focus
[window setLevel:NSFloatingWindowLevel];
} else {
// Focus owner has changed, move the childWindow
// back to normal window level
[window setLevel:NSNormalWindowLevel];
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
NSWindow *window;
while ((window = [windowEnumerator nextObject]) != nil) {
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
AWTWindow *owner = awtWindow.ownerWindow;
if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {
// Do not order 'always on top' windows
continue;
}
if (window.onActiveSpace && owner.onActiveSpace) {
// The childWindow should be displayed in front of
// its nearest parentWindow
[window orderWindow:NSWindowAbove relativeTo:[owner windowNumber]];
while (awtWindow.ownerWindow != nil) {
if (awtWindow.ownerWindow == self) {
if (focus) {
// Move the childWindow to floating level
// so it will appear in front of its
// parent which owns the focus
[window setLevel:NSFloatingWindowLevel];
} else {
// Focus owner has changed, move the childWindow
// back to normal window level
[window setLevel:NSNormalWindowLevel];
}
if (window.onActiveSpace && owner.nsWindow.onActiveSpace) {
// The childWindow should be displayed in front of
// its nearest parentWindow
[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];
}
break;
}
awtWindow = awtWindow.ownerWindow;
}
}
}];
}
}
// NSWindow overrides
@@ -790,14 +783,24 @@ AWT_ASSERT_APPKIT_THREAD;
- (void) iconifyChildWindows:(BOOL)iconify {
AWT_ASSERT_APPKIT_THREAD;
[self processVisibleChildren:^void(AWTWindow* child){
NSWindow *window = child.nsWindow;
if (iconify) {
[window orderOut:window];
} else {
[window orderFront:window];
NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
NSWindow *window;
while ((window = [windowEnumerator nextObject]) != nil) {
if ([AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
while (awtWindow.ownerWindow != nil) {
if (awtWindow.ownerWindow == self) {
if (iconify) {
[window orderOut:window];
} else {
[window orderFront:window];
}
break;
}
awtWindow = awtWindow.ownerWindow;
}
}
}];
}
}
- (void) _deliverIconify:(BOOL)iconify {
@@ -1000,22 +1003,10 @@ AWT_ASSERT_APPKIT_THREAD;
}
}
// this is required to move owned windows to the full-screen space when owner goes to full-screen mode
- (void)allowMovingChildrenBetweenSpaces:(BOOL)allow {
[self processVisibleChildren:^void(AWTWindow* child){
NSWindow *window = child.nsWindow;
NSWindowCollectionBehavior behavior = window.collectionBehavior;
behavior &= !(NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorTransient);
behavior |= allow ? NSWindowCollectionBehaviorTransient : NSWindowCollectionBehaviorManaged;
window.collectionBehavior = behavior;
}];
}
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = YES;
[self allowMovingChildrenBetweenSpaces:YES];
static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
@@ -1028,9 +1019,7 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = YES;
[self allowMovingChildrenBetweenSpaces:NO];
static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
@@ -1514,38 +1503,6 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeHideWindow
* Signature: (JZ)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeHideWindow
(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean wait)
{
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:(BOOL)wait block:^(){
if (nsWindow.keyWindow) {
// When 'windowDidResignKey' is called during 'orderOut', current key window
// is reported as 'nil', so it's impossible to create WINDOW_FOCUS_LOST event
// with correct 'opposite' window.
// So, as a workaround, we perform focus transfer to a parent window explicitly here.
NSWindow *parentWindow = nsWindow;
while ((parentWindow = ((AWTWindow*)parentWindow.delegate).ownerWindow.nsWindow) != nil) {
if (parentWindow.canBecomeKeyWindow) {
[parentWindow makeKeyWindow];
break;
}
}
}
[nsWindow orderOut:nsWindow];
[nsWindow close];
}];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSetNSWindowTitle
@@ -1746,19 +1703,6 @@ JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
if ((([nsWindow styleMask] & NSFullScreenWindowMask) != NSFullScreenWindowMask)) {
if (!NSApp.active) {
// use undocumented approach to avoid focus stealing
NSKeyedArchiver *coder = [[NSKeyedArchiver alloc] init];
[nsWindow encodeRestorableStateWithCoder:coder];
[coder encodeBool:YES forKey:@"NSIsFullScreen"];
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:coder.encodedData];
[nsWindow restoreStateWithCoder:decoder];
[decoder finishDecoding];
[decoder release];
[coder release];
if (nsWindow.styleMask & NSWindowStyleMaskFullScreen) return; // success
// otherwise fall back to standard approach
}
[nsWindow performSelector:toggleFullScreenSelector withObject:nil];
}
}];

View File

@@ -1,110 +0,0 @@
/*
* Copyright 2000-2021 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.apple.eawt.Application;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.nio.file.Files;
/**
* @test
* @summary Regression test for JBR-3686 Background window steals focus when converted to full screen on macOS
* @key headful
* @requires (os.family == "mac")
* @modules java.desktop/com.apple.eawt
*/
public class FullScreenFocusStealing {
private static JFrame frame;
private static Process otherProcess;
public static void main(String[] args) throws Exception {
try {
SwingUtilities.invokeAndWait(FullScreenFocusStealing::initUI);
launchProcessWithWindow();
toggleFullScreen();
Thread.sleep(1000);
assertProcessWindowIsStillFocused();
}
finally {
SwingUtilities.invokeAndWait(FullScreenFocusStealing::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("FullScreenFocusStealing");
frame.setBounds(100, 100, 200, 200);
frame.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
if (otherProcess != null) otherProcess.destroyForcibly();
}
private static void toggleFullScreen() throws Exception {
Application.class.getDeclaredMethod("requestEnterFullScreen", Window.class)
.invoke(Application.getApplication(), frame);
}
private static void assertProcessWindowIsStillFocused() throws Exception {
otherProcess.getOutputStream().write('\n');
otherProcess.getOutputStream().flush();
if (otherProcess.getInputStream().read() != '1') {
throw new RuntimeException("Process window lost focus");
}
}
private static void launchProcessWithWindow() throws Exception {
String javaPath = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
File tmpFile = File.createTempFile("FullScreenFocusStealing", ".java");
tmpFile.deleteOnExit();
Files.writeString(tmpFile.toPath(), "import javax.swing.*;\n" +
"import java.awt.event.*;\n" +
"\n" +
"public class TestWindow {\n" +
" private static JFrame frame;\n" +
" public static void main(String[] args) throws Exception {\n" +
" SwingUtilities.invokeLater(() -> {\n" +
" frame = new JFrame(\"FullScreenFocusStealing 2\");\n" +
" frame.addWindowFocusListener(new WindowAdapter() {\n" +
" @Override\n" +
" public void windowGainedFocus(WindowEvent e) {\n" +
" System.out.println();\n" +
" }\n" +
" });\n" +
" frame.setBounds(100, 400, 200, 200);\n" +
" frame.setVisible(true);\n" +
" });\n" +
" System.in.read();\n" +
" System.out.println(frame.isFocused() ? '1' : '0');\n" +
" }\n" +
"}\n");
otherProcess = Runtime.getRuntime().exec(new String[]{javaPath, tmpFile.getAbsolutePath()});
if (otherProcess.getInputStream().read() == -1) {
throw new RuntimeException("Error starting process");
}
}
}

View File

@@ -1,107 +0,0 @@
/*
* Copyright 2021 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
* @test
* @summary Regression test for JBR-3662 Focus jumps to another project tab after closing modal dialog
* @key headful
*/
public class WrongFrameFocusedOnModalDialogClosing {
private static CompletableFuture<Boolean> result;
private static Robot robot;
private static JFrame frame1;
private static JFrame frame2;
private static JDialog dialog;
private static JButton button;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(WrongFrameFocusedOnModalDialogClosing::initUI);
robot.delay(1000); // wait for frames to appear
clickOn(button);
robot.delay(1000); // wait for dialog to appear
SwingUtilities.invokeAndWait(() -> {
result = new CompletableFuture<>();
dialog.dispose();
});
if (result.get(5, TimeUnit.SECONDS)) {
throw new RuntimeException("Wrong frame focused");
}
} finally {
SwingUtilities.invokeAndWait(WrongFrameFocusedOnModalDialogClosing::disposeUI);
}
}
private static void initUI() {
frame1 = new JFrame("WFFOMDC 1");
frame1.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
if (result != null) result.complete(false);
}
});
dialog = new JDialog(frame1, true);
button = new JButton("Open dialog");
button.addActionListener(e -> dialog.setVisible(true));
frame1.add(button);
frame1.setSize(100, 100);
frame1.setLocation(100, 100);
frame1.setVisible(true);
frame2 = new JFrame("WFFOMDC 2");
frame2.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
if (result != null) result.complete(true);
}
});
frame2.setSize(100, 100);
frame2.setLocation(300, 100);
frame2.setVisible(true);
}
private static void disposeUI() {
if (frame1 != null) frame1.dispose();
if (frame2 != null) frame2.dispose();
}
private static void clickAt(int x, int y) {
robot.mouseMove(x, y);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
private static void clickOn(Component component) {
Point location = component.getLocationOnScreen();
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
}
}

View File

@@ -1,121 +0,0 @@
/*
* Copyright 2000-2021 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.File;
import java.nio.file.Files;
/**
* @test
* @summary Regression test for JBR-3671 Window order changes for a background app on macOS desktop space switch
* @key headful
* @requires (os.family == "mac")
*/
public class BackgroundWindowOrderOnSpaceChange {
private static Robot robot;
private static JFrame frame1;
private static JFrame frame2;
private static Process otherProcess;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(BackgroundWindowOrderOnSpaceChange::initUI);
launchProcessWithWindow();
switchToNextSpace();
switchToPreviousSpace();
Color color = robot.getPixelColor(400, 400);
if (!Color.green.equals(color)) {
throw new RuntimeException("Frame 1 isn't shown on top. Found color: " + color);
}
}
finally {
SwingUtilities.invokeAndWait(BackgroundWindowOrderOnSpaceChange::disposeUI);
}
}
private static void initUI() {
frame1 = new JFrame("BackgroundWindowOrderOnSpaceChange 1");
frame1.getContentPane().setBackground(Color.green);
frame1.setBounds(100, 100, 400, 400);
frame1.setVisible(true);
frame2 = new JFrame("BackgroundWindowOrderOnSpaceChange 2");
frame2.getContentPane().setBackground(Color.red);
frame2.setBounds(300, 300, 400, 400);
frame2.setVisible(true);
frame1.toFront();
}
private static void disposeUI() {
if (frame1 != null) frame1.dispose();
if (frame2 != null) frame2.dispose();
if (otherProcess != null) otherProcess.destroyForcibly();
}
private static void launchProcessWithWindow() throws Exception {
String javaPath = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
File tmpFile = File.createTempFile("BackgroundWindowOrderOnSpaceChange", ".java");
tmpFile.deleteOnExit();
Files.writeString(tmpFile.toPath(), "import javax.swing.*;\n" +
"import java.awt.event.*;\n" +
"\n" +
"public class TestWindow {\n" +
" public static void main(String[] args) {\n" +
" SwingUtilities.invokeLater(() -> {\n" +
" JFrame f = new JFrame(\"BackgroundWindowOrderOnSpaceChange 3\");\n" +
" f.addWindowFocusListener(new WindowAdapter() {\n" +
" @Override\n" +
" public void windowGainedFocus(WindowEvent e) {\n" +
" System.out.println();\n" +
" }\n" +
" });\n" +
" f.setBounds(800, 100, 200, 200);\n" +
" f.setVisible(true);\n" +
" });\n" +
" }\n" +
"}\n");
otherProcess = Runtime.getRuntime().exec(new String[]{javaPath, tmpFile.getAbsolutePath()});
if (otherProcess.getInputStream().read() == -1) {
throw new RuntimeException("Error starting process");
}
}
private static void switchToPreviousSpace() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_LEFT);
robot.keyRelease(KeyEvent.VK_LEFT);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.delay(1000); // wait for animation to finish
}
private static void switchToNextSpace() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_RIGHT);
robot.keyRelease(KeyEvent.VK_RIGHT);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.delay(1000); // wait for animation to finish
}
}

View File

@@ -1,123 +0,0 @@
/*
* Copyright 2021 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.apple.eawt.Application;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
/**
* @test
* @summary Regression test for JBR-3666 Child window stays on default space
* when full-screen mode is activated for parent window on macOS
* @key headful
* @requires (os.family == "mac")
* @modules java.desktop/com.apple.eawt
*/
public class FullScreenChildWindowShownBefore {
private static final CompletableFuture<Boolean> dialogShown = new CompletableFuture<>();
private static Robot robot;
private static JFrame frame;
private static JDialog dialog;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(FullScreenChildWindowShownBefore::initUI);
dialogShown.get(5, TimeUnit.SECONDS);
SwingUtilities.invokeAndWait(() -> Application.getApplication().requestToggleFullScreen(frame));
robot.delay(1000); // wait for transition to full screen to finish
ensureVisible(frame);
ensureVisible(dialog);
} finally {
SwingUtilities.invokeAndWait(FullScreenChildWindowShownBefore::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("FullScreenChildWindowShownBefore");
frame.setSize(100, 100);
frame.setLocation(100, 100);
frame.setVisible(true);
dialog = new JDialog(frame, false);
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
dialogShown.complete(true);
}
});
dialog.setSize(100, 100);
dialog.setLocation(100, 300);
dialog.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
private static void ensureVisible(Window window) throws Exception {
AtomicReference<Point> location = new AtomicReference<>();
AtomicBoolean movementDetected = new AtomicBoolean();
SwingUtilities.invokeAndWait(() -> {
if (window.isVisible()) {
Rectangle bounds = window.getBounds();
Insets insets = window.getInsets();
bounds.x += insets.left;
bounds.y += insets.top;
bounds.width -= insets.left + insets.right;
bounds.height -= insets.top + insets.bottom;
if (!bounds.isEmpty()) {
location.set(new Point((int) bounds.getCenterX(), (int) bounds.getCenterY()));
window.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
movementDetected.set(true);
}
});
}
}
});
Point target = location.get();
if (target != null) {
robot.mouseMove(target.x, target.y);
robot.delay(100);
robot.mouseMove(target.x + 1, target.y + 1);
robot.delay(1000);
if (movementDetected.get()) {
return;
}
}
throw new RuntimeException(window + " isn't visible");
}
}

View File

@@ -1,109 +0,0 @@
/*
* Copyright 2000-2021 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @test
* @summary Regression test for JBR-3676 WINDOW_ACTIVATED/DEACTIVATED events
* sent to a frame when child window closes on macOS
* @key headful
*/
public class WindowEventsOnPopupShowing {
private static final AtomicInteger events = new AtomicInteger();
private static Robot robot;
private static JFrame frame;
private static JButton openButton;
private static JButton closeButton;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(WindowEventsOnPopupShowing::initUI);
robot.delay(1000); // wait for frame to be shown
events.set(0);
clickAt(openButton);
robot.delay(1000); // wait for popup to be shown
clickAt(closeButton);
robot.delay(1000); // wait for popup to be closed
int eventCount = events.get();
if (eventCount != 0) {
throw new RuntimeException("Unexpected events received: " + eventCount);
}
}
finally {
SwingUtilities.invokeAndWait(WindowEventsOnPopupShowing::disposeUI);
}
}
private static void initUI() {
openButton = new JButton("Open popup");
closeButton = new JButton("Close");
frame = new JFrame("WindowEventsOnPopupShowing");
frame.add(openButton);
frame.pack();
JWindow popup = new JWindow(frame);
popup.add(closeButton);
popup.pack();
openButton.addActionListener(e -> popup.setVisible(true));
closeButton.addActionListener(e -> popup.dispose());
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
events.incrementAndGet();
}
@Override
public void windowDeactivated(WindowEvent e) {
events.incrementAndGet();
}
});
frame.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
private static void clickAt(int x, int y) {
robot.mouseMove(x, y);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
private static void clickAt(Component component) {
Point location = component.getLocationOnScreen();
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
}
}

View File

@@ -1275,5 +1275,6 @@ jb/java/jcef/MouseEventTest.java
jb/java/jcef/MouseEventAfterHideAndShowBrowserTest.java JBR-2750 linux-all
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTest.java nobug windows-6.1 not supported on Windows 7
jb/java/awt/Focus/ChainOfPopupsFocusTest.java JBR-1518 linux-all
jb/java/awt/Focus/ModalDialogFromMenuTest.java JBR-2768 macosx-all
java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java JBR-2842 macosx-10.14,macosx-10.15,macosx-10.16

View File

@@ -211,6 +211,7 @@ jb/javax/swing/JDialog/JDialog705.java
jb/javax/swing/JDialog/JDialog741/JDialog741.html nobug macosx-all,linux-all,windows-all
jb/sun/awt/macos/KeyPressAndHoldTest.java nobug macosx-all
jb/sun/lwawt/macosx/NSEvent/nsevent422.sh nobug macosx-all
jb/java/awt/Focus/ModalDialogFromMenuTest.java JBR-2768 macosx-all
jb/java/jcef/MouseEventTest.java JBR-2750 linux-all
jb/java/jcef/MouseEventAfterHideAndShowBrowserTest.java JBR-2750 linux-all