mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-25 02:39:43 +01:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2cdacaddd | ||
|
|
2e925883d5 | ||
|
|
a156c6b9bf | ||
|
|
75335543f2 | ||
|
|
c9143a3b22 | ||
|
|
8361529140 | ||
|
|
2988403307 | ||
|
|
43fdd6cd26 | ||
|
|
9e16583b83 | ||
|
|
390fc567ef | ||
|
|
3674766d65 | ||
|
|
3b0708af7d | ||
|
|
995e2643c6 | ||
|
|
ff7ca94ca3 | ||
|
|
4a393c0243 | ||
|
|
b4316f0317 | ||
|
|
404a4329c7 | ||
|
|
504f91d4d1 | ||
|
|
0895519455 | ||
|
|
ba57c58ac7 |
141
README.md
141
README.md
@@ -1,84 +1,145 @@
|
||||
[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
|
||||
|
||||
# How JetBrains Runtime is organised
|
||||
## Workspaces
|
||||
# Welcome to JetBrains Runtime!
|
||||
|
||||
[github.com/JetBrains/JetBrainsRuntime](https://github.com/JetBrains/JetBrainsRuntime)
|
||||
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.
|
||||
|
||||
## Getting sources
|
||||
__macOS, Linux:__
|
||||
## 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)
|
||||
- [Getting Sources](#getting-sources)
|
||||
- [macOS, Linux](#macos-linux)
|
||||
- [Windows](#sources-windows)
|
||||
- [Configuring the Build Environment](#configuring-the-build-environment)
|
||||
- [Linux (Docker)](#linux-docker)
|
||||
- [Ubuntu Linux](#ubuntu-linux)
|
||||
- [Windows](#build-windows)
|
||||
- [macOS](#macos)
|
||||
- [Contributing](#contributing)
|
||||
- [Resources](#resources)
|
||||
|
||||
## Products Built on JetBrains Runtime
|
||||
* [Android Studio](https://developer.android.com/studio). The official IDE for Google's Android operating system.
|
||||
* [CLion](https://www.jetbrains.com/clion/). A cross-platform IDE for C and C++ from JetBrains.
|
||||
* [DataGrip](https://www.jetbrains.com/datagrip/). The IDE for Databases and SQL from JetBrains.
|
||||
* [GoLand](https://www.jetbrains.com/go/). The cross-platform Go IDE from JetBrains.
|
||||
* [IntelliJ IDEA](https://www.jetbrains.com/idea/). The IDE for JVM from JetBrains.
|
||||
* [JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html). The Java profiler.
|
||||
* [PhpStorm](https://www.jetbrains.com/phpstorm/). The PHP IDE from JetBrains.
|
||||
* [PyCharm](https://www.jetbrains.com/pycharm/). The Python IDE from JetBrains.
|
||||
* [Rider](https://www.jetbrains.com/rider/). The cross-platform .NET IDE from JetBrains.
|
||||
* [RubyMine](https://www.jetbrains.com/ruby/). The Ruby and Rails IDE from JetBrains.
|
||||
* [WebStorm](https://www.jetbrains.com/webstorm/). The JavaScript IDE from JetBrains.
|
||||
* [YourKit](https://www.yourkit.com/). Java and .NET profilers.
|
||||
|
||||
## Getting Sources
|
||||
### macOS, Linux
|
||||
```
|
||||
git config --global core.autocrlf input
|
||||
git clone git@github.com:JetBrains/JetBrainsRuntime.git
|
||||
```
|
||||
|
||||
__Windows:__
|
||||
### Windows
|
||||
<a name="sources-windows"></a>
|
||||
```
|
||||
git config --global core.autocrlf false
|
||||
git clone git@github.com:JetBrains/JetBrainsRuntime.git
|
||||
```
|
||||
|
||||
# Configure local build environment
|
||||
[OpenJDK build docs](http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html)
|
||||
Tip for all platforms: run `./configure` and check output.
|
||||
Usually, it has meaningful advice how to solve your problem.
|
||||
## Configuring the Build Environment
|
||||
Here are quick per-platform instructions for those who can't wait to get started.
|
||||
Please refer to [OpenJDK build docs](http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html) for in-depth
|
||||
coverage of all the details.
|
||||
|
||||
## Linux (Docker)
|
||||
> **_TIP:_** To get a preliminary report of what's missing, run `./configure` and check its output.
|
||||
> It would usually have a meaningful advice on how to solve the problem.
|
||||
|
||||
### Linux (Docker)
|
||||
Create a container:
|
||||
```
|
||||
$ cd jb/project/docker
|
||||
$ docker build .
|
||||
...
|
||||
Successfully built 942ea9900054
|
||||
|
||||
```
|
||||
Run these commands in the new container:
|
||||
```
|
||||
$ docker run -v `pwd`../../../../:/JetBrainsRuntime -it 942ea9900054
|
||||
|
||||
# cd /JetBrainsRuntime
|
||||
# sh ./configure
|
||||
# make images CONF=linux-x86_64-normal-server-release
|
||||
```
|
||||
|
||||
## Linux (Ubuntu 18.10 desktop)
|
||||
### Ubuntu Linux
|
||||
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 \
|
||||
openjdk-11-jdk
|
||||
```
|
||||
Then run the following:
|
||||
```
|
||||
$ 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
|
||||
|
||||
$ cd JetBrainsRuntime
|
||||
$ sh ./configure --disable-warnings-as-errors
|
||||
$ make images
|
||||
```
|
||||
|
||||
## Windows
|
||||
Install:
|
||||
* [Cygwin x64](http://www.cygwin.com/)
|
||||
Required packages: autoconf, binutils, cpio, diffutils, file, gawk, gcc-core, make, m4, unzip, zip.
|
||||
**Install them while installing Cygwin**.
|
||||
* Visual Studio compiler toolset [Download](https://visualstudio.microsoft.com/downloads/)
|
||||
Visual Studio 2015 has support by default.
|
||||
**Install with desktop development kit, it includes Windows SDK and compilers**.
|
||||
* [Java 11](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
|
||||
If you have problems while configuring [read Java tips on Cygwin](http://horstmann.com/articles/cygwin-tips.html)
|
||||
### Windows
|
||||
<a name="build-windows"></a>
|
||||
Install the following:
|
||||
* [Cygwin x64](http://www.cygwin.com/).
|
||||
Required packages: `autoconf`, `binutils`, `cpio`, `diffutils`, `file`, `gawk`, `gcc-core`, `make`, `m4`, `unzip`, `zip`.
|
||||
Install those together with Cygwin.
|
||||
* [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](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 command line:
|
||||
From the command line:
|
||||
```
|
||||
"c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
|
||||
"c:\Program_Files\cygwin64\bin\mintty.exe" /bin/bash -l
|
||||
```
|
||||
First command will set env vars, the second will run Cygwin shell with proper environment.
|
||||
The first command sets up environment variables, the second starts a Cygwin shell with the proper environment.
|
||||
|
||||
In Cygwin shell:
|
||||
```
|
||||
cd JetBrainsRuntime
|
||||
bash configure --enable-option-checking=fatal --with-toolchain-version=2015 --with-boot-jdk="/cygdrive/c/Program Files/Java/jdk-11.0.5" --disable-warnings-as-errors
|
||||
make images
|
||||
In the Cygwin shell:
|
||||
```
|
||||
$ cd JetBrainsRuntime
|
||||
$ bash configure --enable-option-checking=fatal --with-toolchain-version=2015 \
|
||||
--with-boot-jdk="/cygdrive/c/Program Files/Java/jdk-11.0.5" --disable-warnings-as-errors
|
||||
$ make images
|
||||
```
|
||||
|
||||
## macOS
|
||||
Install Xcode command line developer tools, autoconf (via Homebrew).
|
||||
### macOS
|
||||
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).
|
||||
|
||||
Run:
|
||||
From the command line:
|
||||
```
|
||||
sh ./configure --prefix=$(pwd)/build --disable-warnings-as-errors
|
||||
make images
|
||||
$ cd JetBrainsRuntime
|
||||
$ sh ./configure --prefix=$(pwd)/build --disable-warnings-as-errors
|
||||
$ make images
|
||||
```
|
||||
|
||||
## Contribution
|
||||
We will be happy to receive your pull requests. Before you submit one, please sign our Contributor License Agreement (CLA) https://www.jetbrains.com/agreements/cla/
|
||||
## Contributing
|
||||
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/).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -63,6 +63,9 @@ class CAccessible extends CFRetainedResource implements Accessible {
|
||||
return newCAX;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread);
|
||||
|
||||
private static native void unregisterFromCocoaAXSystem(long ptr);
|
||||
private static native void valueChanged(long ptr);
|
||||
private static native void selectedTextChanged(long ptr);
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
* correct AppKit threading and Objective-C GC semantics.
|
||||
*/
|
||||
public class CFRetainedResource {
|
||||
private static native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread);
|
||||
protected native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread);
|
||||
|
||||
private final boolean disposeOnAppKitThread;
|
||||
// TODO this pointer should be private and accessed via CFNativeAction class
|
||||
|
||||
@@ -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
|
||||
@@ -1291,16 +1328,18 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
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);
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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", "()Z");
|
||||
JNFCallBooleanMethod(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) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,28 @@
|
||||
|
||||
#import "sun_lwawt_macosx_CFRetainedResource.h"
|
||||
|
||||
void nativeCFRelease(JNIEnv *env, jlong ptr, jboolean releaseOnAppKitThread, bool (^condition)(jlong))
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
if (releaseOnAppKitThread) {
|
||||
// Releasing resources on the main AppKit message loop only
|
||||
// Releasing resources on the nested loops may cause dangling
|
||||
// pointers after the nested loop is exited
|
||||
if ([NSApp respondsToSelector:@selector(postRunnableEvent:)]) {
|
||||
[NSApp postRunnableEvent:^() {
|
||||
if (condition(ptr)) CFRelease(jlong_to_ptr(ptr));
|
||||
}];
|
||||
} else {
|
||||
// could happen if we are embedded inside SWT/FX application,
|
||||
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
|
||||
if (condition(ptr)) CFRelease(jlong_to_ptr(ptr));
|
||||
}];
|
||||
}
|
||||
} else {
|
||||
if (condition(ptr)) CFRelease(jlong_to_ptr(ptr));
|
||||
}
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CFRetainedResource
|
||||
@@ -35,29 +57,7 @@
|
||||
* Signature: (JZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CFRetainedResource_nativeCFRelease
|
||||
(JNIEnv *env, jclass clazz, jlong ptr, jboolean releaseOnAppKitThread)
|
||||
(JNIEnv *env, jobject peer, jlong ptr, jboolean releaseOnAppKitThread)
|
||||
{
|
||||
if (releaseOnAppKitThread) {
|
||||
// Releasing resources on the main AppKit message loop only
|
||||
// Releasing resources on the nested loops may cause dangling
|
||||
// pointers after the nested loop is exited
|
||||
if ([NSApp respondsToSelector:@selector(postRunnableEvent:)]) {
|
||||
[NSApp postRunnableEvent:^() {
|
||||
CFRelease(jlong_to_ptr(ptr));
|
||||
}];
|
||||
} else {
|
||||
// could happen if we are embedded inside SWT/FX application,
|
||||
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
|
||||
CFRelease(jlong_to_ptr(ptr));
|
||||
}];
|
||||
}
|
||||
} else {
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
CFRelease(jlong_to_ptr(ptr));
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
}
|
||||
nativeCFRelease(env, ptr, true, ^bool (jlong ptr) { return true; });
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
// for example, for AccessibleJTreeNode, whose currentComponent has index -1
|
||||
+ (JavaComponentAccessibility *) createWithAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env withView:(NSView *)view isCurrent:(BOOL)current;
|
||||
|
||||
+ (bool) isAllocated:(long)ptr;
|
||||
|
||||
@property(readonly) jobject accessible;
|
||||
@property(readonly) jobject component;
|
||||
@property(readonly) jint index;
|
||||
|
||||
@@ -46,6 +46,8 @@ static JNF_MEMBER_CACHE(jm_getAccessibleContext, sjc_CAccessible, "getAccessible
|
||||
|
||||
static jobject sAccessibilityClass = NULL;
|
||||
|
||||
NSMutableArray *sJavaComponentAccessibilityPtrs = nil; // a list of pointers to allocated JavaComponentAccessibility objects
|
||||
|
||||
static void RaiseMustOverrideException(NSString *method)
|
||||
{
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
@@ -55,6 +57,24 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
|
||||
@implementation JavaComponentAccessibility
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
if (sJavaComponentAccessibilityPtrs == nil) {
|
||||
sJavaComponentAccessibilityPtrs = [[NSMutableArray alloc] init];
|
||||
[sJavaComponentAccessibilityPtrs retain]; // per-process persistent
|
||||
}
|
||||
[sJavaComponentAccessibilityPtrs addObject:[NSNumber numberWithLong:(jlong)self]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (bool) isAllocated:(long)ptr
|
||||
{
|
||||
assert([NSThread isMainThread]);
|
||||
return [sJavaComponentAccessibilityPtrs containsObject:[NSNumber numberWithLong:ptr]];
|
||||
}
|
||||
|
||||
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
|
||||
{
|
||||
self = [self init];
|
||||
@@ -94,6 +114,8 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
||||
|
||||
[sJavaComponentAccessibilityPtrs removeObject:[NSNumber numberWithLong:(jlong)self]];
|
||||
|
||||
(*env)->DeleteWeakGlobalRef(env, fAccessible);
|
||||
fAccessible = NULL;
|
||||
|
||||
@@ -220,11 +242,13 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
}
|
||||
|
||||
+ (jobject) getCAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env {
|
||||
JNF_COCOA_DURING(env);
|
||||
if (JNFIsInstanceOf(env, jaccessible, &sjc_CAccessible)) {
|
||||
return jaccessible;
|
||||
} else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) {
|
||||
return JNFCallStaticObjectMethod(env, sjm_getCAccessible, jaccessible);
|
||||
}
|
||||
JNF_COCOA_HANDLE(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -329,11 +353,13 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
{
|
||||
JavaComponentAccessibility *ret = nil;
|
||||
jobject jcomponent = [(AWTView *)view awtComponent:env];
|
||||
JNF_COCOA_DURING(env);
|
||||
jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent);
|
||||
NSString *javaRole = getJavaRole(env, jaccessible, jcomponent);
|
||||
if ((index >= 0) || current) {
|
||||
ret = [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view];
|
||||
}
|
||||
JNF_COCOA_HANDLE(env);
|
||||
(*env)->DeleteLocalRef(env, jcomponent);
|
||||
return ret;
|
||||
}
|
||||
@@ -519,11 +545,6 @@ static void RaiseMustOverrideException(NSString *method)
|
||||
return size;
|
||||
}
|
||||
|
||||
- (id)getFocusedElement
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (jobject)accessible {
|
||||
return fAccessible;
|
||||
}
|
||||
@@ -564,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]];
|
||||
@@ -852,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
|
||||
@@ -1152,9 +1173,29 @@ JNF_COCOA_EXIT(env);
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSystem
|
||||
(JNIEnv *env, jclass jklass, jlong element)
|
||||
(JNIEnv *env, jclass jklass, jlong ptr)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
[ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
|
||||
[ThreadUtilities performOnMainThreadWaiting:NO block:^() {
|
||||
if ([JavaComponentAccessibility isAllocated:ptr]) {
|
||||
[(JavaComponentAccessibility *)jlong_to_ptr(ptr) unregisterFromCocoaAXSystem];
|
||||
}
|
||||
}];
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
extern void nativeCFRelease(JNIEnv *env, jlong ptr, jboolean releaseOnAppKitThread, bool (^condition)(jlong));
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_CAccessible
|
||||
* Method: nativeCFRelease
|
||||
* Signature: (IZ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_nativeCFRelease
|
||||
(JNIEnv *env, jobject peer, jlong ptr, jboolean releaseOnAppKitThread)
|
||||
{
|
||||
assert(releaseOnAppKitThread);
|
||||
nativeCFRelease(env, ptr, true, ^bool (jlong ptr) {
|
||||
return [JavaComponentAccessibility isAllocated:ptr];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -341,14 +341,14 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
|| ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom())
|
||||
{
|
||||
if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
|
||||
if (getWindowTitleVisibleProperty().isPresent()) {
|
||||
if (getMWMDecorTitleProperty().isPresent()) {
|
||||
// Insets might have changed "in-flight" if that property
|
||||
// is present, so we need to get the actual values of
|
||||
// insets from the WM and propagate them through all the
|
||||
// proper channels.
|
||||
wm_set_insets = null;
|
||||
Insets in = getWMSetInsets(XAtom.get(ev.get_atom()));
|
||||
if (!in.equals(dimensions.getInsets())) {
|
||||
if (in != null && !in.equals(dimensions.getInsets())) {
|
||||
handleCorrectInsets(in);
|
||||
}
|
||||
} else {
|
||||
@@ -1333,15 +1333,14 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
super.handleWindowFocusOut(oppositeWindow, serial);
|
||||
}
|
||||
|
||||
// Client properties
|
||||
public static final String WINDOW_TITLE_VISIBLE = "linux.awt.windowTitleVisible";
|
||||
public static final String MWM_DECOR_TITLE_PROPERTY_NAME = "xawt.mwm_decor_title";
|
||||
|
||||
public final Optional<Boolean> getWindowTitleVisibleProperty() {
|
||||
public final Optional<Boolean> getMWMDecorTitleProperty() {
|
||||
Optional<Boolean> res = Optional.empty();
|
||||
|
||||
if (target instanceof javax.swing.RootPaneContainer) {
|
||||
if (SunToolkit.isInstanceOf(target, "javax.swing.RootPaneContainer")) {
|
||||
javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer) target).getRootPane();
|
||||
Object prop = rootpane.getClientProperty(WINDOW_TITLE_VISIBLE);
|
||||
Object prop = rootpane.getClientProperty(MWM_DECOR_TITLE_PROPERTY_NAME);
|
||||
if (prop != null) {
|
||||
res = Optional.of(Boolean.parseBoolean(prop.toString()));
|
||||
}
|
||||
@@ -1351,6 +1350,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
}
|
||||
|
||||
public final boolean getWindowTitleVisible() {
|
||||
return getWindowTitleVisibleProperty().orElse(true);
|
||||
return getMWMDecorTitleProperty().orElse(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.awt.Insets;
|
||||
import java.awt.MenuBar;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.peer.FramePeer;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
@@ -50,9 +51,6 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
|
||||
private static final int MENUBAR_HEIGHT_IF_NO_MENUBAR = 0;
|
||||
private int lastAppliedMenubarHeight = MENUBAR_HEIGHT_IF_NO_MENUBAR;
|
||||
|
||||
// Client properties
|
||||
public static final String WINDOW_TITLE_VISIBLE = "linux.awt.windowTitleVisible";
|
||||
|
||||
XFramePeer(Frame target) {
|
||||
super(target);
|
||||
}
|
||||
@@ -84,9 +82,9 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
|
||||
}
|
||||
|
||||
private void registerWindowDecorationChangeListener() {
|
||||
if (target instanceof javax.swing.RootPaneContainer) {
|
||||
if (SunToolkit.isInstanceOf(target, "javax.swing.RootPaneContainer")) { // avoid unnecessary class loading
|
||||
javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer) target).getRootPane();
|
||||
rootpane.addPropertyChangeListener(WINDOW_TITLE_VISIBLE, e -> winAttr.decorations = getWindowDecorationBits() );
|
||||
rootpane.addPropertyChangeListener(MWM_DECOR_TITLE_PROPERTY_NAME, e -> winAttr.decorations = getWindowDecorationBits() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,15 +96,15 @@ class XFramePeer extends XDecoratedPeer implements FramePeer {
|
||||
decorations = XWindowAttributesData.AWT_DECOR_ALL;
|
||||
|
||||
if (!getWindowTitleVisible()) {
|
||||
// NB: window must be [re-]mapped to make this change effective. Also, window insets will probably
|
||||
// NB: the window must be [re-]mapped to make this change effective. Also, window insets will probably
|
||||
// change and that'll be caught by one of the subsequent property change events in XDecoratedPeer
|
||||
// (not necessarily the next event, though).
|
||||
// (not necessarily the very next event, though).
|
||||
decorations = XWindowAttributesData.AWT_DECOR_BORDER;
|
||||
}
|
||||
|
||||
if (log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
log.fine("Frame''s initial decorations affected by the client property {0}={1}",
|
||||
WINDOW_TITLE_VISIBLE, getWindowTitleVisibleProperty());
|
||||
MWM_DECOR_TITLE_PROPERTY_NAME, getMWMDecorTitleProperty());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,11 +185,13 @@ public class XRGlyphCacheEntry {
|
||||
}
|
||||
|
||||
public byte getSubpixelResolutionX() {
|
||||
return StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.subpixelResolutionXOffset);
|
||||
byte rx = StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.subpixelResolutionXOffset);
|
||||
return rx < 1 ? 1 : rx;
|
||||
}
|
||||
|
||||
public byte getSubpixelResolutionY() {
|
||||
return StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.subpixelResolutionYOffset);
|
||||
byte ry = StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.subpixelResolutionYOffset);
|
||||
return ry < 1 ? 1 : ry;
|
||||
}
|
||||
|
||||
public long getGlyphInfoPtr() {
|
||||
|
||||
4068
test/hotspot/jtreg/compiler/c1/TestTooManyVirtualRegisters.jasm
Normal file
4068
test/hotspot/jtreg/compiler/c1/TestTooManyVirtualRegisters.jasm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ requires.properties= \
|
||||
vm.hasSAandCanAttach \
|
||||
vm.hasJFR \
|
||||
docker.support \
|
||||
release.implementor
|
||||
release.implementor \
|
||||
display.XWayland
|
||||
|
||||
# Minimum jtreg version
|
||||
requiredVersion=4.2 b12
|
||||
|
||||
@@ -25,10 +25,11 @@
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @summary Verifies client property for Linux linux.awt.windowTitleVisible.
|
||||
* @summary Verifies the client property xawt.mwm_decor_title for Linux.
|
||||
* Note: the test requires GNOME Shell window manager and will automatically
|
||||
* pass with any other WM.
|
||||
* @requires (os.family == "linux")
|
||||
* @requires !display.XWayland
|
||||
* @run main WindowTitleVisibleTestLinuxGnome
|
||||
*/
|
||||
|
||||
@@ -83,7 +84,7 @@ public class WindowTitleVisibleTestLinuxGnome
|
||||
captureTitleBarNotVisible();
|
||||
|
||||
if (imagesEqual(titleBarImageVisible, titleBarImageNotVisible)) {
|
||||
throw new RuntimeException("Test failed: title bar shown and hidden are the same.");
|
||||
throw new RuntimeException("Test failed: title bars shown and hidden are the same.");
|
||||
}
|
||||
|
||||
runSwing(() -> frame.dispose());
|
||||
@@ -107,23 +108,19 @@ public class WindowTitleVisibleTestLinuxGnome
|
||||
}
|
||||
|
||||
private void captureTitleBarNotVisible() {
|
||||
runSwing( () -> {
|
||||
titleBarImageNotVisible = robot.createScreenCapture(titleBarBounds);
|
||||
});
|
||||
titleBarImageNotVisible = robot.createScreenCapture(titleBarBounds);
|
||||
}
|
||||
|
||||
private void hideTitleBar() {
|
||||
runSwing( () -> {
|
||||
rootPane.putClientProperty("linux.awt.windowTitleVisible", false);
|
||||
rootPane.putClientProperty("xawt.mwm_decor_title", false);
|
||||
frame.setVisible(false);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
private void captureTitleBarVisible() {
|
||||
runSwing( () -> {
|
||||
titleBarImageVisible = robot.createScreenCapture(titleBarBounds);
|
||||
});
|
||||
titleBarImageVisible = robot.createScreenCapture(titleBarBounds);
|
||||
}
|
||||
|
||||
private void constructAndShowFrame() {
|
||||
@@ -131,7 +128,7 @@ public class WindowTitleVisibleTestLinuxGnome
|
||||
frame = new JFrame("IIIIIIIIIIIIIIII");
|
||||
frame.setBounds(100, 100, 300, 150);
|
||||
rootPane = frame.getRootPane();
|
||||
rootPane.putClientProperty("linux.awt.windowTitleVisible", true);
|
||||
rootPane.putClientProperty("xawt.mwm_decor_title", true);
|
||||
JComponent contentPane = (JComponent) frame.getContentPane();
|
||||
JPanel comp = new JPanel();
|
||||
contentPane.add(comp);
|
||||
|
||||
129
test/jdk/jb/java/awt/Window/FullScreenChildWindow.java
Normal file
129
test/jdk/jb/java/awt/Window/FullScreenChildWindow.java
Normal 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);
|
||||
}
|
||||
}
|
||||
145
test/jdk/jb/java/awt/Window/FullScreenInactiveModalDialog.java
Normal file
145
test/jdk/jb/java/awt/Window/FullScreenInactiveModalDialog.java
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -837,12 +837,17 @@ com/sun/nio/sctp/SctpChannel/SocketOptionTests.java
|
||||
|
||||
sun/security/lib/cacerts/VerifyCACerts.java 8240268 generic-all
|
||||
sun/security/pkcs11/ec/TestKeyFactory.java 8026976 generic-all
|
||||
sun/security/pkcs11/Secmod/AddTrustedCert.java 8180837 generic-all
|
||||
sun/security/pkcs11/tls/TestKeyMaterial.java 8180837 generic-all
|
||||
|
||||
sun/security/pkcs11/KeyStore/SecretKeysBasic.sh 8209398 generic-all
|
||||
sun/security/pkcs11/Secmod/AddTrustedCert.java 8180837 generic-all
|
||||
sun/security/pkcs11/tls/TestKeyMaterial.java 8180837 generic-all
|
||||
|
||||
security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 generic-all
|
||||
security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java 8243543 generic-all
|
||||
security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 8263059 generic-all
|
||||
security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java 8268678 generic-all
|
||||
security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 8248899 generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
@@ -117,6 +117,7 @@ public class VMProps implements Callable<Map<String, String>> {
|
||||
map.put("vm.compiler2.enabled", this::isCompiler2Enabled);
|
||||
map.put("docker.support", this::dockerSupport);
|
||||
map.put("release.implementor", this::implementor);
|
||||
map.put("display.XWayland", this::displayXWayland);
|
||||
vmGC(map); // vm.gc.X = true/false
|
||||
vmOptFinalFlags(map);
|
||||
|
||||
@@ -515,6 +516,13 @@ public class VMProps implements Callable<Map<String, String>> {
|
||||
}
|
||||
}
|
||||
|
||||
protected String displayXWayland() {
|
||||
final boolean isXWayland = (System.getenv("WAYLAND_DISPLAY") != null)
|
||||
&& (System.getenv("DISPLAY") != null);
|
||||
|
||||
return String.valueOf(isXWayland);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the map to the file if the file name is given as the property.
|
||||
* This functionality could be helpful to know context in the real
|
||||
|
||||
Reference in New Issue
Block a user