Compare commits

..

15 Commits
1548 ... 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
Dmitry Batrak
9fdc75969b JBR-3633 Modal dialog is shown not at the same space as its parent
fix the case when space switch is performed by clicking on app icon in dock, or using Cmd+Tab
2021-07-30 18:59:20 +03:00
Dmitry Batrak
c2cdacaddd JBR-3560 [JCK] java.awt.Dialog should throw java.lang.IllegalArgumentException: Wrong parent window
rollback JBR-1255 fix
2021-07-23 20:26:25 +03:00
Artem Semenov
2e925883d5 JBR-3637: Eliminate JBR build warnings from a11y 2021-07-23 15:59:16 +03:00
Dmitry Batrak
a156c6b9bf JBR-3633 Modal dialog is shown not at the same space as its parent 2021-07-21 14:51:39 +03:00
Dmitry Batrak
75335543f2 JBR-3611 Unexpected workspace switch with dialog in full-screen mode on macOS
make test pass with jtreg
2021-07-21 14:51:39 +03:00
Maxim Kartashev
c9143a3b22 JBR-3626 Apply fix for 8261235 to JBR11
8261235: C1 compilation fails with assert(res->vreg_number() == index) failed: conversion check

Reviewed-by: thartmann, kvn
2021-07-20 08:36:23 -07:00
Vitaly Provodin
8361529140 update the link to JBR for IDEA 2021.2 RC 2021-07-20 14:40:55 +07:00
Maxim Kartashev
2988403307 fixup! JBR-3618 Add info about releases to JBR README on github 2021-07-19 14:53:45 +03:00
Dmitry Batrak
43fdd6cd26 JBR-3611 Unexpected workspace switch with dialog in full-screen mode on macOS 2021-07-19 10:11:44 +03:00
Maxim Kartashev
9e16583b83 JBR-3618 Add info about releases to JBR README on github 2021-07-16 16:41:54 +03:00
Artem Semenov
390fc567ef JBR-3609: Eliminate regressions caused by JBR-3437 2021-07-16 14:08:55 +03:00
Dmitry Batrak
3674766d65 JBR-3598 [JCK] KEY_TYPED event is not dispatched
another part of the fix
2021-07-14 20:47:54 +03:00
Dmitry Batrak
3b0708af7d JBR-3598 [JCK] KEY_TYPED event is not dispatched 2021-07-14 20:37:14 +03:00
25 changed files with 4780 additions and 103 deletions

View File

@@ -5,6 +5,16 @@
JetBrains Runtime is a fork of [OpenJDK](https://github.com/openjdk/jdk) available for Windows, Mac OS X, and Linux.
It includes a number enhancements in font rendering, HiDPI support, ligatures, performance improvements, and bugfixes.
## Releases
Download the latest releases of JetBrains Runtime to use with JetBrains IDEs. The full list
can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntime/releases).
| IDE Version | Latest JBR | Date Released |
| --- | --- | --- |
| 2021.2 | [11_0_11-b1504.13](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jb11_0_11-b1504.13) | 19-Jul-2021 |
| 2021.1 | [11.0.11+9-b1341.60](https://confluence.jetbrains.com/pages/viewpage.action?pageId=218857477) | 15-Jun-2021 |
| 2020.3 | [11_0_11-b1145.115](https://confluence.jetbrains.com/pages/viewpage.action?pageId=219349001) | 21-Jun-2021 |
## Contents
- [Welcome to JetBrains Runtime](#jetbrains-runtime)
- [Products Built on JetBrains Runtime](#products-built-on-jetbrains-runtime)
@@ -75,7 +85,8 @@ $ docker run -v `pwd`../../../../:/JetBrainsRuntime -it 942ea9900054
Install the necessary tools, libraries, and headers with:
```
$ sudo apt-get install autoconf make build-essential libx11-dev libxext-dev libxrender-dev libxtst-dev \
libxt-dev libxrandr-dev libcups2-dev libfontconfig1-dev libasound2-dev
libxt-dev libxrandr-dev libcups2-dev libfontconfig1-dev libasound2-dev \
openjdk-11-jdk
```
Then run the following:
```
@@ -93,7 +104,7 @@ Install the following:
* [Visual Studio compiler toolset](https://visualstudio.microsoft.com/downloads/).
Install with the desktop development kit, which includes Windows SDK and compilers.
Visual Studio 2015 is supported by default.
* [Java 11](http://www.oracle.com/technetwork/java/javase/downloads/index.html).
* [Java 11](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html).
If you have problems while configuring, read [Java tips on Cygwin](http://horstmann.com/articles/cygwin-tips.html).
From the command line:
@@ -112,7 +123,9 @@ $ make images
```
### macOS
Install Xcode command line developer tools and `autoconf` via [Homebrew](getDpiInfo).
Install the following:
* Xcode command line developer tools and `autoconf` via [Homebrew](getDpiInfo).
* [Java 11](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html).
From the command line:
```
@@ -126,7 +139,7 @@ We are happy to receive your pull requests!
Before you submit one, please sign our [Contributor License Agreement (CLA)](https://www.jetbrains.com/agreements/cla/).
## Resources
* [JetBrains Runtime on github](https://github.com/JetBrains/JetBrainsRuntime)
* [OpenJDK build instructions](http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html)
* [OpenJDK test instructions](http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html#running-tests)
* [How to develop OpenJDK with CLion](https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/)
* [JetBrains Runtime on github](https://github.com/JetBrains/JetBrainsRuntime).
* [OpenJDK build instructions](http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html).
* [OpenJDK test instructions](http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html#running-tests).
* [How to develop OpenJDK with CLion](https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/).

View File

@@ -230,8 +230,8 @@ class LIR_OprDesc: public CompilationResourceObj {
, is_xmm_bits = 1
, last_use_bits = 1
, is_fpu_stack_offset_bits = 1 // used in assertion checking on x86 for FPU stack slot allocation
, non_data_bits = kind_bits + type_bits + size_bits + destroys_bits + last_use_bits +
is_fpu_stack_offset_bits + virtual_bits + is_xmm_bits
, non_data_bits = pointer_bits + kind_bits + type_bits + size_bits + destroys_bits + virtual_bits
+ is_xmm_bits + last_use_bits + is_fpu_stack_offset_bits
, data_bits = BitsPerInt - non_data_bits
, reg_bits = data_bits / 2 // for two registers in one value encoding
};
@@ -648,6 +648,11 @@ class LIR_OprFact: public AllStatic {
#endif // X86
static LIR_Opr virtual_register(int index, BasicType type) {
if (index > LIR_OprDesc::vreg_max) {
// Running out of virtual registers. Caller should bailout.
return illegalOpr;
}
LIR_Opr res;
switch (type) {
case T_OBJECT: // fall through

View File

@@ -1047,20 +1047,21 @@ void LIRGenerator::move_to_phi(ValueStack* cur_state) {
LIR_Opr LIRGenerator::new_register(BasicType type) {
int vreg = _virtual_register_number;
// add a little fudge factor for the bailout, since the bailout is
// only checked periodically. This gives a few extra registers to
// hand out before we really run out, which helps us keep from
// tripping over assertions.
if (vreg + 20 >= LIR_OprDesc::vreg_max) {
bailout("out of virtual registers");
if (vreg + 2 >= LIR_OprDesc::vreg_max) {
// wrap it around
int vreg_num = _virtual_register_number;
// Add a little fudge factor for the bailout since the bailout is only checked periodically. This allows us to hand out
// a few extra registers before we really run out which helps to avoid to trip over assertions.
if (vreg_num + 20 >= LIR_OprDesc::vreg_max) {
bailout("out of virtual registers in LIR generator");
if (vreg_num + 2 >= LIR_OprDesc::vreg_max) {
// Wrap it around and continue until bailout really happens to avoid hitting assertions.
_virtual_register_number = LIR_OprDesc::vreg_base;
vreg_num = LIR_OprDesc::vreg_base;
}
}
_virtual_register_number += 1;
return LIR_OprFact::virtual_register(vreg, type);
LIR_Opr vreg = LIR_OprFact::virtual_register(vreg_num, type);
assert(vreg != LIR_OprFact::illegal(), "ran out of virtual registers");
return vreg;
}

View File

@@ -3884,8 +3884,8 @@ void MoveResolver::insert_move(Interval* from_interval, Interval* to_interval) {
assert(_insert_list != NULL && _insert_idx != -1, "must setup insert position first");
assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer");
LIR_Opr from_opr = LIR_OprFact::virtual_register(from_interval->reg_num(), from_interval->type());
LIR_Opr to_opr = LIR_OprFact::virtual_register(to_interval->reg_num(), to_interval->type());
LIR_Opr from_opr = get_virtual_register(from_interval);
LIR_Opr to_opr = get_virtual_register(to_interval);
if (!_multiple_reads_allowed) {
// the last_use flag is an optimization for FPU stack allocation. When the same
@@ -3903,12 +3903,27 @@ void MoveResolver::insert_move(LIR_Opr from_opr, Interval* to_interval) {
assert(_insert_list != NULL && _insert_idx != -1, "must setup insert position first");
assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer");
LIR_Opr to_opr = LIR_OprFact::virtual_register(to_interval->reg_num(), to_interval->type());
LIR_Opr to_opr = get_virtual_register(to_interval);
_insertion_buffer.move(_insert_idx, from_opr, to_opr);
TRACE_LINEAR_SCAN(4, tty->print("MoveResolver: inserted move from constant "); from_opr->print(); tty->print_cr(" to %d (%d, %d)", to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi()));
}
LIR_Opr MoveResolver::get_virtual_register(Interval* interval) {
// Add a little fudge factor for the bailout since the bailout is only checked periodically. This allows us to hand out
// a few extra registers before we really run out which helps to avoid to trip over assertions.
int reg_num = interval->reg_num();
if (reg_num + 20 >= LIR_OprDesc::vreg_max) {
_allocator->bailout("out of virtual registers in linear scan");
if (reg_num + 2 >= LIR_OprDesc::vreg_max) {
// Wrap it around and continue until bailout really happens to avoid hitting assertions.
reg_num = LIR_OprDesc::vreg_base;
}
}
LIR_Opr vreg = LIR_OprFact::virtual_register(reg_num, interval->type());
assert(vreg != LIR_OprFact::illegal(), "ran out of virtual registers");
return vreg;
}
void MoveResolver::resolve_mappings() {
TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: resolving mappings for Block B%d, index %d", _insert_list->block() != NULL ? _insert_list->block()->block_id() : -1, _insert_idx));

View File

@@ -430,6 +430,7 @@ class MoveResolver: public StackObj {
void append_insertion_buffer();
void insert_move(Interval* from_interval, Interval* to_interval);
void insert_move(LIR_Opr from_opr, Interval* to_interval);
LIR_Opr get_virtual_register(Interval* interval);
DEBUG_ONLY(void verify_before_resolve();)
void resolve_mappings();

View File

@@ -1342,7 +1342,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
public Point windowToLocal(Point p, LWWindowPeer wp) {
LWComponentPeer<?, ?> cp = this;
while (cp != wp) {
while (cp != wp && cp != null) {
Rectangle cpb = cp.getBounds();
p.x -= cpb.x;
p.y -= cpb.y;

View File

@@ -35,6 +35,7 @@ import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.MenuBar;
import java.awt.Point;
import java.awt.Rectangle;
@@ -42,9 +43,11 @@ import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.FocusEvent;
import java.awt.event.WindowEvent;
import java.awt.peer.ComponentPeer;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@@ -69,11 +72,8 @@ import sun.lwawt.LWToolkit;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.LWWindowPeer.PeerType;
import sun.lwawt.PlatformWindow;
import sun.util.logging.PlatformLogger;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
import sun.util.logging.PlatformLogger;
public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
@@ -107,6 +107,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native void nativeEnterFullScreenMode(long nsWindowPtr);
private static native void nativeExitFullScreenMode(long nsWindowPtr);
static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
private static native boolean nativeDelayShowing(long nsWindowPtr);
// Loger to report issues happened during execution but that do not affect functionality
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
@@ -733,6 +734,16 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
return this.visible;
}
private static LWWindowPeer getBlockerFor(Window window) {
if (window != null) {
ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(window);
if (peer instanceof LWWindowPeer) {
return ((LWWindowPeer)peer).getBlocker();
}
}
return null;
}
@Override // PlatformWindow
public void setVisible(boolean visible) {
// Configure stuff
@@ -749,7 +760,17 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Actually show or hide the window
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
if (blocker == null || !visible) {
if (visible && delayShowing()) {
if (blocker == null) {
Window focusedWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
LWWindowPeer focusedWindowBlocker = getBlockerFor(focusedWindow);
if (focusedWindowBlocker == peer) {
// try to switch to target space if we're adding a modal dialog
// that would block currently focused window
owner.execute(CWrapper.NSWindow::orderFront);
}
}
} else if (blocker == null || !visible) {
// If it ain't blocked, or is being hidden, go regular way
if (visible) {
boolean isPopup = (target.getType() == Window.Type.POPUP);
@@ -844,7 +865,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Manage parent-child relationship when showing
final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
if (visible) {
if (visible && !delayShowing()) {
// Order myself above my parent
if (owner != null && owner.isVisible()) {
owner.execute(ownerPtr -> {
@@ -876,7 +897,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// Deal with the blocker of the window being shown
if (blocker != null && visible) {
// Make sure the blocker is above its siblings
((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
CPlatformWindow blockerWindow = (CPlatformWindow) blocker.getPlatformWindow();
if (!blockerWindow.delayShowing()) {
blockerWindow.orderAboveSiblings();
}
}
}
@@ -911,6 +935,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
@Override // PlatformWindow
public void toFront() {
if (delayShowing()) return;
LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
@@ -965,6 +990,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
@Override
public boolean requestWindowFocus() {
if (delayShowing()) return false;
execute(ptr -> {
if (CWrapper.NSWindow.canBecomeMainWindow(ptr)) {
CWrapper.NSWindow.makeMainWindow(ptr);
@@ -983,6 +1009,17 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
return ref.get();
}
// We want a window to be always shown at the same space as its owning window.
// But macOS doesn't have an API to control the target space for a window -
// it's always shown at the active space. So if the target space isn't active now,
// the only way to achieve our goal seems to be delaying the appearance of the
// window till the target space becomes active.
private boolean delayShowing() {
AtomicBoolean ref = new AtomicBoolean(false);
execute(ptr -> ref.set(nativeDelayShowing(ptr)));
return ref.get();
}
@Override
public void updateFocusableWindowState() {
setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, getFocusableStyleBits()); // set both bits at once
@@ -1101,7 +1138,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
}
nativeSetEnabled(ptr, !blocked);
});
checkBlockingAndOrder();
}
public final void invalidateShadow() {
@@ -1279,29 +1315,32 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
isFocusable ? focusableStyleBits : 0); // set both bits at once
}
private boolean checkBlockingAndOrder() {
private void checkBlockingAndOrder() {
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
if (blocker == null) {
return false;
// If it's not blocked, make sure it's above its siblings
orderAboveSiblings();
return;
}
if (blocker instanceof CPrinterDialogPeer) {
return true;
return;
}
CPlatformWindow pWindow = (CPlatformWindow)blocker.getPlatformWindow();
pWindow.orderAboveSiblings();
if (!pWindow.delayShowing()) {
pWindow.orderAboveSiblings();
pWindow.execute(ptr -> {
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
logger.fine("Focus blocker " + Long.toHexString(ptr));
}
CWrapper.NSWindow.orderFrontRegardless(ptr);
CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
CWrapper.NSWindow.makeMainWindow(ptr);
});
return true;
pWindow.execute(ptr -> {
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
logger.fine("Focus blocker " + Long.toHexString(ptr));
}
CWrapper.NSWindow.orderFrontRegardless(ptr);
CWrapper.NSWindow.makeKeyAndOrderFront(ptr);
CWrapper.NSWindow.makeMainWindow(ptr);
});
}
}
private boolean isIconified() {
@@ -1363,7 +1402,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
if (p instanceof LWWindowPeer) {
CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
iconified = isIconified();
if (pw != null && pw.isVisible() && !iconified) {
if (pw != null && pw.isVisible() && !iconified && !pw.delayShowing()) {
// If the window is one of ancestors of 'main window' or is going to become main by itself,
// the window should be ordered above its siblings; otherwise the window is just ordered
// above its nearest parent.
@@ -1435,9 +1474,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private void windowDidBecomeMain() {
lastBecomeMainTime = System.currentTimeMillis();
if (checkBlockingAndOrder()) return;
// If it's not blocked, make sure it's above its siblings
orderAboveSiblings();
checkBlockingAndOrder();
}
private void windowWillEnterFullScreen() {

View File

@@ -867,7 +867,7 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
id focused = [self accessibilityFocusedUIElement];
if ([focused respondsToSelector:@selector(setAccessibilitySelectedText)]) {
if ([focused respondsToSelector:@selector(setAccessibilitySelectedText:)]) {
[focused setAccessibilitySelectedText:accessibilitySelectedText];
}
}

View File

@@ -376,9 +376,10 @@ AWT_NS_WINDOW_IMPLEMENTATION
if (IS(mask, FULLSCREENABLE) && [self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {
if (IS(bits, FULLSCREENABLE)) {
[self.nsWindow setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
[self.nsWindow setCollectionBehavior:
NSWindowCollectionBehaviorFullScreenPrimary | NSWindowCollectionBehaviorManaged];
} else {
[self.nsWindow setCollectionBehavior:NSWindowCollectionBehaviorDefault];
[self.nsWindow setCollectionBehavior: NSWindowCollectionBehaviorManaged];
}
}
@@ -441,10 +442,6 @@ AWT_ASSERT_APPKIT_THREAD;
self.ownerWindow = owner;
[self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
if (IS(self.styleBits, IS_POPUP)) {
[self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];
}
self.javaWindowTabbingMode = [self getJavaWindowTabbingMode];
self.isEnterFullScreen = NO;
self.isJustCreated = YES;
@@ -601,6 +598,43 @@ AWT_ASSERT_APPKIT_THREAD;
return isVisible;
}
- (BOOL) delayShowing {
AWT_ASSERT_APPKIT_THREAD;
return ownerWindow != nil && ([ownerWindow delayShowing] || !ownerWindow.nsWindow.onActiveSpace)
&& !nsWindow.visible;
}
- (void) checkBlockingAndOrder {
AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,
"checkBlockingAndOrder", "()V");
JNFCallVoidMethod(env, platformWindow, jm_checkBlockingAndOrder);
(*env)->DeleteLocalRef(env, platformWindow);
}
}
+ (void)activeSpaceDidChange {
AWT_ASSERT_APPKIT_THREAD;
for (NSWindow* window in [NSApp windows]) {
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
if (awtWindow.ownerWindow == nil) {
// this should ensure that delayed blocking windows
// show up on space activation
[awtWindow checkBlockingAndOrder];
}
}
}
}
// Orders window's childs based on the current focus state
- (void) orderChildWindows:(BOOL)focus {
AWT_ASSERT_APPKIT_THREAD;
@@ -632,9 +666,11 @@ AWT_ASSERT_APPKIT_THREAD;
// back to normal window level
[window setLevel:NSNormalWindowLevel];
}
// The childWindow should be displayed in front of
// its nearest parentWindow
[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];
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;
@@ -668,14 +704,7 @@ AWT_ASSERT_APPKIT_THREAD;
// We should bring up the modal dialog manually
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,
"checkBlockingAndOrder", "()Z");
JNFCallBooleanMethod(env, platformWindow, jm_checkBlockingAndOrder);
(*env)->DeleteLocalRef(env, platformWindow);
}
[self checkBlockingAndOrder];
}
return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);
@@ -1805,3 +1834,25 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeDelayShowing
* Signature: (J)Z
*/
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeDelayShowing
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
__block jboolean result = JNI_FALSE;
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = (NSWindow *)jlong_to_ptr(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
result = [window delayShowing];
}];
JNF_COCOA_EXIT(env);
return result;
}

View File

@@ -38,7 +38,7 @@
#import "CMenuBar.h"
#import "ThreadUtilities.h"
#import "NSApplicationAWT.h"
#import "AWTWindow.h"
#pragma mark App Menu helpers
@@ -258,6 +258,11 @@ AWT_ASSERT_APPKIT_THREAD;
[ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil];
[ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:[AWTWindow class]
selector:@selector(activeSpaceDidChange)
name:NSWorkspaceActiveSpaceDidChangeNotification
object:nil];
return self;
}

View File

@@ -16,12 +16,12 @@
if (children == NULL) {
NSString *javaRole = [self javaRole];
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:self
accessible:self->fAccessible
role:javaRole
index:self->fIndex
withEnv:[ThreadUtilities getJNIEnv]
withView:self->fView
isWrapped:YES];
accessible:self->fAccessible
role:javaRole
index:self->fIndex
withEnv:[ThreadUtilities getJNIEnv]
withView:self->fView
isWrapped:NO];
return [NSArray arrayWithObject:newChild];
} else {
return children;

View File

@@ -33,8 +33,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
NSUInteger childIndex = [self columnNumberInTable];
int inc = [(JavaTableAccessibility *)[self accessibilityParent] accessibleColCount] * 2;
NSInteger i = childIndex * 2;
for(NSInteger i; i < arrayLen; i += inc)
for(NSInteger i = childIndex * 2; i < arrayLen; i += inc)
{
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
@@ -52,7 +51,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
withIndex:childIndex
withView:self->fView
withJavaRole:childJavaRole];
[childrenCells addObject:[child autorelease]];
[childrenCells addObject:[[child retain] autorelease]];
(*env)->DeleteLocalRef(env, jchild);
(*env)->DeleteLocalRef(env, jchildJavaRole);

View File

@@ -545,11 +545,6 @@ static void RaiseMustOverrideException(NSString *method)
return size;
}
- (id)getFocusedElement
{
}
- (jobject)accessible {
return fAccessible;
}
@@ -590,13 +585,13 @@ static void RaiseMustOverrideException(NSString *method)
if (axAction != NULL) {
JNF_CLASS_CACHE(jc_AccessibleAction, "javax/accessibility/AccessibleAction");
JNF_MEMBER_CACHE(jm_getAccessibleActionCount, jc_AccessibleAction, "getAccessibleActionCount", "()I");
jint count = JNFCallObjectMethod(env, axAction, jm_getAccessibleActionCount);
jint count = JNFCallIntMethod(env, axAction, jm_getAccessibleActionCount);
fActions = [[NSMutableDictionary alloc] initWithCapacity:count];
fActionSElectors = [[NSMutableArray alloc] initWithCapacity:count];
for (int i =0; i < count; i++) {
JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:i withComponent:fComponent];
if ([fParent isKindOfClass:[JavaComponentAccessibility class]] &&
[fParent isMenu] &&
[(JavaComponentAccessibility *)fParent isMenu] &&
[[sActions objectForKey:[action getDescription]] isEqualToString:NSAccessibilityPressAction]) {
[fActions setObject:action forKey:NSAccessibilityPickAction];
[fActionSElectors addObject:[sActionSelectores objectForKey:NSAccessibilityPickAction]];
@@ -878,16 +873,16 @@ static void RaiseMustOverrideException(NSString *method)
// cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz
if (isVertical(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityVerticalOrientationValue;
return NSAccessibilityOrientationVertical;
}
if (isHorizontal(env, axContext, fComponent)) {
(*env)->DeleteLocalRef(env, axContext);
return NSAccessibilityHorizontalOrientationValue;
return NSAccessibilityOrientationHorizontal;
}
(*env)->DeleteLocalRef(env, axContext);
return nil;
return NSAccessibilityOrientationUnknown;
}
- (NSPoint)accessibilityActivationPoint

View File

@@ -20,14 +20,16 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
- (NSArray *)accessibilityChildren {
NSArray *children = [super accessibilityChildren];
if (children == NULL) {
// Since the row element has already been created, we should no create it again, but just retrieve it by a pointer, that's why isWrapped is set to YES.
JavaComponentAccessibility *newChild = [JavaComponentAccessibility createWithParent:self
accessible:self->fAccessible
role:self->fJavaRole
index:self->fIndex
withEnv:[ThreadUtilities getJNIEnv]
withView:self->fView
isWrapped:YES];
return [NSArray arrayWithObject:[newChild autorelease]];
accessible:self->fAccessible
role:self->fJavaRole
index:self->fIndex
withEnv:[ThreadUtilities getJNIEnv]
withView:self->fView
isWrapped:YES];
return [NSArray arrayWithObject:newChild];
} else {
return children;
}

View File

@@ -56,7 +56,7 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
if (row < 0) return 0;
return row;
}
@@ -168,7 +168,7 @@ static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAc
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
if (row < 0) return 0;
return row;
}

View File

@@ -42,7 +42,10 @@ static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject componen
// NSAccessibilityElement protocol methods
- (NSAccessibilitySubrole)accessibilitySubrole {
return NSAccessibilityTabButtonSubrole;
if (@available(macOS 10.13, *)) {
return NSAccessibilityTabButtonSubrole;
}
return NSAccessibilityUnknownSubrole;
}
- (id)accessibilityValue {

View File

@@ -35,9 +35,8 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
NSMutableArray *childrenCells = [NSMutableArray arrayWithCapacity:arrayLen/2];
NSUInteger childIndex = [self rowNumberInTable] * [(JavaTableAccessibility *)parent accessibleColCount];
NSInteger i = childIndex * 2;
NSInteger n = ([self rowNumberInTable] + 1) * [(JavaTableAccessibility *)parent accessibleColCount] * 2;
for(i; i < n; i+=2)
for (NSInteger i = childIndex * 2; i < n; i+=2)
{
jobject /* Accessible */ jchild = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i);
jobject /* String */ jchildJavaRole = (*env)->GetObjectArrayElement(env, jchildrenAndRoles, i+1);
@@ -55,7 +54,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
withIndex:childIndex
withView:self->fView
withJavaRole:childJavaRole];
[childrenCells addObject:[child autorelease]];
[childrenCells addObject:[[child retain] autorelease]];
(*env)->DeleteLocalRef(env, jchild);
(*env)->DeleteLocalRef(env, jchildJavaRole);
@@ -70,7 +69,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getC
}
- (NSInteger)accessibilityIndex {
return [[self accessibilityParent] accessibilityIndexOfChild:self];
return fIndex;
}
- (NSString *)accessibilityLabel {

View File

@@ -870,7 +870,9 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
* @see Component#dispatchEvent
*/
public boolean dispatchKeyEvent(KeyEvent e) {
Component focusOwner = (((AWTEvent)e).isPosted && e.getID() != KeyEvent.KEY_TYPED) ? getFocusOwner() : e.getComponent();
Component focusOwner = (((AWTEvent)e).isPosted &&
!(e.getID() == KeyEvent.KEY_TYPED && SunToolkit.isSystemGenerated(e)))
? getFocusOwner() : e.getComponent();
if (focusOwner != null && focusOwner.isShowing() && focusOwner.canBeFocusOwner()) {
if (!e.isConsumed()) {
@@ -1098,14 +1100,18 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
private boolean preDispatchKeyEvent(KeyEvent ke) {
getOnTypeaheadFinishedHandler().accept(ke);
if (((AWTEvent) ke).isPosted) {
boolean typedEvent = ke.getID() == KeyEvent.KEY_TYPED;
boolean systemEvent = SunToolkit.isSystemGenerated(ke);
Component focusOwner;
if (ke.getID() == KeyEvent.KEY_TYPED) {
if (typedEvent && systemEvent) {
focusOwner = lastKeyPressedOrReleasedTarget.get();
} else {
focusOwner = getFocusOwner();
if (focusOwner == null) {
focusOwner = getFocusedWindow();
}
}
if (!typedEvent && systemEvent) {
lastKeyPressedOrReleasedTarget = new WeakReference<>(focusOwner);
}
ke.setSource(focusOwner);

View File

@@ -663,6 +663,13 @@ public class Dialog extends Window {
public Dialog(Window owner, String title, ModalityType modalityType) {
super(owner);
if ((owner != null) &&
!(owner instanceof Frame) &&
!(owner instanceof Dialog))
{
throw new IllegalArgumentException("Wrong parent window");
}
this.title = title;
setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this);

View File

@@ -1071,7 +1071,13 @@ public class Window extends Container implements Accessible {
} else {
// fix for 6532736: after this window is shown, its blocker
// should be raised to front
modalBlocker.toFront_NoClientCode();
boolean storedValue = modalBlocker.isAutoRequestFocus();
modalBlocker.setAutoRequestFocus(false);
try {
modalBlocker.toFront_NoClientCode();
} finally {
modalBlocker.setAutoRequestFocus(storedValue);
}
}
if (this instanceof Frame || this instanceof Dialog) {
updateChildFocusableWindowState(this);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021, 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
* 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.
*/
/*
* @test
* @bug 8261235
* @requires vm.compiler1.enabled
* @summary Tests custom bytecode which requires too many virtual registers in the linear scan of C1.
* The test should bail out in C1.
*
* @compile TestTooManyVirtualRegisters.jasm
* @run main/othervm -Xbatch -XX:CompileCommand=dontinline,compiler.c1.TestExceptionBlockWithPredecessors::*
* compiler.c1.TestTooManyVirtualRegistersMain
*/
package compiler.c1;
public class TestTooManyVirtualRegistersMain {
public static void main(String[] args) {
for (char i = 0; i < 10000; i++) {
TestTooManyVirtualRegisters.test(i);
}
}
}

View File

@@ -0,0 +1,129 @@
/*
* 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 com.apple.eawt.FullScreenAdapter;
import com.apple.eawt.FullScreenUtilities;
import com.apple.eawt.event.FullScreenEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
* @test
* @summary Regression test for JBR-3611 Unexpected workspace switch with dialog in full-screen mode on macOS
* @key headful
* @requires (os.family == "mac")
* @modules java.desktop/com.apple.eawt
* java.desktop/com.apple.eawt.event
*/
public class FullScreenChildWindow {
private static final CompletableFuture<Boolean> shownAtFullScreen = new CompletableFuture<>();
private static final CompletableFuture<Boolean> dialogShown = new CompletableFuture<>();
private static Robot robot;
private static JFrame frame2;
private static JFrame frame1;
private static JButton button;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(FullScreenChildWindow::initUI);
shownAtFullScreen.get(5, TimeUnit.SECONDS);
clickAt(button);
dialogShown.get(5, TimeUnit.SECONDS);
switchToPreviousSpace();
robot.delay(2000);
if (!frame1.isFocused()) {
throw new RuntimeException("Unexpected state");
}
} finally {
SwingUtilities.invokeAndWait(FullScreenChildWindow::disposeUI);
}
}
private static void initUI() {
frame1 = new JFrame("FullScreenChildWindow(1)");
frame1.setSize(100, 100);
frame1.setLocation(100, 100);
frame1.setVisible(true);
frame2 = new JFrame("FullScreenChildWindow(2)");
button = new JButton("Open dialog");
button.addActionListener(e -> {
JDialog d = new JDialog(frame2, "dialog", false);
d.setSize(100, 100);
d.setLocationRelativeTo(null);
d.setAutoRequestFocus(false);
d.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
dialogShown.complete(true);
}
});
d.setVisible(true);
});
frame2.add(button);
frame2.setSize(100, 100);
frame2.setLocation(100, 300);
frame2.setVisible(true);
FullScreenUtilities.addFullScreenListenerTo(frame2, new FullScreenAdapter() {
@Override
public void windowEnteredFullScreen(FullScreenEvent e) {
shownAtFullScreen.complete(true);
}
});
Application.getApplication().requestToggleFullScreen(frame2);
}
private static void disposeUI() {
if (frame2 != null) frame2.dispose();
if (frame1 != null) frame1.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);
}
private static void switchToPreviousSpace() {
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_LEFT);
robot.keyRelease(KeyEvent.VK_LEFT);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
}

View File

@@ -0,0 +1,145 @@
/*
* 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 com.apple.eawt.FullScreenAdapter;
import com.apple.eawt.FullScreenUtilities;
import com.apple.eawt.event.FullScreenEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @test
* @summary Regression test for JBR-3633 Modal dialog is shown not at the same space as its parent
* @key headful
* @requires (os.family == "mac")
* @modules java.desktop/com.apple.eawt
* java.desktop/com.apple.eawt.event
*/
public class FullScreenInactiveDialog {
private static final CompletableFuture<Boolean> shownAtFullScreen = 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(FullScreenInactiveDialog::initUI);
shownAtFullScreen.get(5, TimeUnit.SECONDS);
switchToPreviousSpace();
SwingUtilities.invokeLater(FullScreenInactiveDialog::openDialog);
robot.delay(1000);
if (isWindowReallyShowing(dialog)) {
throw new RuntimeException("Dialog is showing earlier than expected");
}
activateApp(); // simulates clicking on app icon in dock or switch using Cmd+Tab
if (!isWindowReallyShowing(dialog)) {
throw new RuntimeException("Dialog isn't showing when expected");
}
if (!isWindowReallyShowing(frame)) {
throw new RuntimeException("Frame isn't showing when expected");
}
} finally {
SwingUtilities.invokeAndWait(FullScreenInactiveDialog::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("FullScreenInactiveDialog");
frame.setSize(300, 100);
frame.setVisible(true);
FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenAdapter() {
@Override
public void windowEnteredFullScreen(FullScreenEvent e) {
shownAtFullScreen.complete(true);
}
});
Application.getApplication().requestToggleFullScreen(frame);
}
private static void openDialog() {
dialog = new JDialog(frame);
dialog.setSize(100, 100);
dialog.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
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 activateApp() {
Desktop.getDesktop().requestForeground(false);
robot.delay(1000); // wait for animation to finish
}
private static boolean isWindowReallyShowing(Window window) throws Exception {
Point[] location = new Point[1];
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[0] = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
window.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
movementDetected.set(true);
}
});
}
}
});
Point target = location[0];
if (target == null) {
return false;
}
robot.mouseMove(target.x, target.y);
robot.delay(100);
robot.mouseMove(target.x + 1, target.y + 1);
robot.delay(1000);
return movementDetected.get();
}
}

View File

@@ -0,0 +1,145 @@
/*
* 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 com.apple.eawt.FullScreenAdapter;
import com.apple.eawt.FullScreenUtilities;
import com.apple.eawt.event.FullScreenEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @test
* @summary Regression test for JBR-3633 Modal dialog is shown not at the same space as its parent
* @key headful
* @requires (os.family == "mac")
* @modules java.desktop/com.apple.eawt
* java.desktop/com.apple.eawt.event
*/
public class FullScreenInactiveModalDialog {
private static final CompletableFuture<Boolean> shownAtFullScreen = 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(FullScreenInactiveModalDialog::initUI);
shownAtFullScreen.get(5, TimeUnit.SECONDS);
switchToPreviousSpace();
SwingUtilities.invokeLater(FullScreenInactiveModalDialog::openDialog);
robot.delay(1000);
if (isWindowReallyShowing(dialog)) {
throw new RuntimeException("Dialog is showing earlier than expected");
}
switchToNextSpace();
if (!isWindowReallyShowing(dialog)) {
throw new RuntimeException("Dialog isn't showing when expected");
}
} finally {
SwingUtilities.invokeAndWait(FullScreenInactiveModalDialog::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("FullScreenInactiveModalDialog");
frame.setSize(300, 100);
frame.setVisible(true);
FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenAdapter() {
@Override
public void windowEnteredFullScreen(FullScreenEvent e) {
shownAtFullScreen.complete(true);
}
});
Application.getApplication().requestToggleFullScreen(frame);
}
private static void openDialog() {
dialog = new JDialog(frame, true);
dialog.setSize(100, 100);
dialog.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
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
}
private static boolean isWindowReallyShowing(Window window) throws Exception {
Point[] location = new Point[1];
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[0] = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
window.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
movementDetected.set(true);
}
});
}
}
});
Point target = location[0];
if (target == null) {
return false;
}
robot.mouseMove(target.x, target.y);
robot.delay(100);
robot.mouseMove(target.x + 1, target.y + 1);
robot.delay(1000);
return movementDetected.get();
}
}