mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-05 08:01:39 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5d96e6747 | ||
|
|
995841e5e3 | ||
|
|
008b01e11d | ||
|
|
88e71f2056 | ||
|
|
867686a430 | ||
|
|
1855d8955c | ||
|
|
8a14c80209 | ||
|
|
c7d906e7c7 | ||
|
|
a9475c85cd | ||
|
|
1f9cdefaef | ||
|
|
5e5239464a | ||
|
|
62a3f98138 | ||
|
|
cea6ac1be5 | ||
|
|
a170b4e4ae | ||
|
|
c9609330f2 | ||
|
|
1750c6f390 | ||
|
|
fb725c15c4 |
@@ -11,6 +11,7 @@ can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntim
|
||||
|
||||
| IDE Version | Latest JBR | Date Released |
|
||||
| --- | --- | --- |
|
||||
| 2022.3 | [17.0.4.1-b597.1](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.4.1b597.1)| 12-Sep-2022 |
|
||||
| 2022.2 | [17.0.4-b469.53](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.4b469.53)| 31-Aug-2022 |
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,14 @@ BOOT_JDK=${BOOT_JDK:=$(/usr/libexec/java_home -v 16)}
|
||||
|
||||
function do_configure {
|
||||
if [[ "${architecture}" == *aarch64* ]]; then
|
||||
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
|
||||
WITH_EXTRA_CFLAGS="--with-extra-cflags="-F$(pwd)/$JCEF_PATH/Frameworks"
|
||||
--with-extra-cxxflags="-F$(pwd)/$JCEF_PATH/Frameworks"
|
||||
--with-extra-ldflags="-F$(pwd)/$JCEF_PATH/Frameworks" "
|
||||
else
|
||||
WITH_EXTRA_CFLAGS=""
|
||||
fi
|
||||
sh configure \
|
||||
$WITH_DEBUG_LEVEL \
|
||||
--with-vendor-name="${VENDOR_NAME}" \
|
||||
@@ -43,9 +51,7 @@ function do_configure {
|
||||
--with-macosx-version-max="${MACOSX_VERSION_MAX:="11.00.00"}" \
|
||||
--disable-hotspot-gtest --disable-javac-server --disable-full-docs --disable-manpages \
|
||||
--enable-cds=no \
|
||||
--with-extra-cflags="-F$(pwd)/Frameworks" \
|
||||
--with-extra-cxxflags="-F$(pwd)/Frameworks" \
|
||||
--with-extra-ldflags="-F$(pwd)/Frameworks" \
|
||||
$WITH_EXTRA_CFLAGS \
|
||||
$STATIC_CONF_ARGS \
|
||||
$REPRODUCIBLE_BUILD_OPTS \
|
||||
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
|
||||
|
||||
@@ -66,8 +66,11 @@ import java.util.Map;
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
class _AppEventHandler {
|
||||
private static final PlatformLogger logger = PlatformLogger.getLogger(_AppEventHandler.class.getName());
|
||||
|
||||
private static final int NOTIFY_ABOUT = 1;
|
||||
private static final int NOTIFY_PREFS = 2;
|
||||
private static final int NOTIFY_OPEN_APP = 3;
|
||||
@@ -267,10 +270,13 @@ class _AppEventHandler {
|
||||
instance.systemSleepDispatcher.dispatch(new _NativeEvent(Boolean.FALSE));
|
||||
break;
|
||||
case NOTIFY_SCREEN_CHANGE_PARAMETERS:
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
logger.fine("NOTIFY_SCREEN_CHANGE_PARAMETERS");
|
||||
}
|
||||
if (AppContext.getAppContext() != null) {
|
||||
EventQueue.invokeLater(
|
||||
() -> ((SunGraphicsEnvironment)SunGraphicsEnvironment.
|
||||
getLocalGraphicsEnvironment()).displayChanged());
|
||||
getLocalGraphicsEnvironment()).displayParametersChanged());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -46,7 +46,7 @@ import sun.util.logging.PlatformLogger;
|
||||
import static java.awt.peer.ComponentPeer.SET_BOUNDS;
|
||||
|
||||
public final class CGraphicsDevice extends GraphicsDevice
|
||||
implements DisplayChangedListener {
|
||||
implements DisplayChangedListener, DisplayParametersChangedListener {
|
||||
|
||||
private static final PlatformLogger logger = PlatformLogger.getLogger(CGraphicsDevice.class.getName());
|
||||
/**
|
||||
@@ -74,11 +74,12 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
public CGraphicsDevice(final int displayID) {
|
||||
this.displayID = displayID;
|
||||
this.initialMode = getDisplayMode();
|
||||
StringBuilder errorMessage = new StringBuilder();
|
||||
|
||||
if (MacOSFlags.isMetalEnabled()) {
|
||||
// Try to create MTLGraphicsConfig, if it fails,
|
||||
// try to create CGLGraphicsConfig as a fallback
|
||||
this.config = MTLGraphicsConfig.getConfig(this, displayID);
|
||||
this.config = MTLGraphicsConfig.getConfig(this, displayID, errorMessage);
|
||||
|
||||
if (this.config != null) {
|
||||
metalPipelineEnabled = true;
|
||||
@@ -88,7 +89,7 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
// Should not fall back to OpenGL if Metal has been used before
|
||||
// (it could cause CCE during replace of surface data)
|
||||
throw new InternalError("Error - unable to initialize Metal" +
|
||||
" after recreation of graphics device.");
|
||||
" after recreation of graphics device." + errorMessage);
|
||||
}
|
||||
|
||||
// Try falling back to OpenGL pipeline
|
||||
@@ -119,7 +120,7 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
" rendering pipeline");
|
||||
}
|
||||
|
||||
this.config = MTLGraphicsConfig.getConfig(this, displayID);
|
||||
this.config = MTLGraphicsConfig.getConfig(this, displayID, errorMessage);
|
||||
|
||||
if (this.config != null) {
|
||||
metalPipelineEnabled = true;
|
||||
@@ -131,7 +132,7 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
// This indicates fallback to other rendering pipeline also failed.
|
||||
// Should never reach here
|
||||
throw new InternalError("Error - unable to initialize any" +
|
||||
" rendering pipeline.");
|
||||
" rendering pipeline." + errorMessage);
|
||||
}
|
||||
|
||||
if (metalPipelineEnabled && MacOSFlags.isMetalVerbose()) {
|
||||
@@ -223,6 +224,20 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||
//TODO configs?
|
||||
}
|
||||
|
||||
public void displayParametersChanged() {
|
||||
Insets newScreenInsets = nativeGetScreenInsets(displayID);
|
||||
if (!newScreenInsets.equals(screenInsets)) {
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
logger.fine("Screen insets for display(" + displayID + ") changed " +
|
||||
"[top=" + screenInsets.top + ",left=" + screenInsets.left +
|
||||
",bottom=" + screenInsets.bottom + ",right=" + screenInsets.right +
|
||||
"]->[top=" + newScreenInsets.top + ",left=" + newScreenInsets.left +
|
||||
",bottom=" + newScreenInsets.bottom + ",right=" + newScreenInsets.right +
|
||||
"]");
|
||||
}
|
||||
screenInsets = newScreenInsets;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void paletteChanged() {
|
||||
// devices do not need to react to this event.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package sun.java2d.metal;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
import sun.awt.CGraphicsConfig;
|
||||
import sun.awt.CGraphicsDevice;
|
||||
import sun.awt.image.OffScreenImage;
|
||||
@@ -72,6 +73,11 @@ import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_BIOP_SHADER;
|
||||
public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
implements AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig
|
||||
{
|
||||
@Native private final static int LOAD_LIB_ERROR = -1;
|
||||
@Native private final static int LOAD_LIB_OK = 0;
|
||||
@Native private final static int LOAD_LIB_NO_DEVICE = 1;
|
||||
@Native private final static int LOAD_LIB_NO_SHADER_LIB = 2;
|
||||
|
||||
private static boolean mtlAvailable;
|
||||
private static boolean mtlUsed = false;
|
||||
private static ImageCapabilities imageCaps = new MTLImageCaps();
|
||||
@@ -91,7 +97,7 @@ public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
private final int maxTextureSize;
|
||||
|
||||
private static native boolean isMetalFrameworkAvailable();
|
||||
private static native boolean tryLoadMetalLibrary(int displayID, String shaderLib);
|
||||
private static native int tryLoadMetalLibrary(int displayID, String shaderLib);
|
||||
private static native long getMTLConfigInfo(int displayID, String mtlShadersLib);
|
||||
|
||||
/**
|
||||
@@ -132,21 +138,29 @@ public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
}
|
||||
|
||||
public static MTLGraphicsConfig getConfig(CGraphicsDevice device,
|
||||
int displayID)
|
||||
int displayID, StringBuilder errorMessage)
|
||||
{
|
||||
if (!mtlAvailable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!tryLoadMetalLibrary(displayID, mtlShadersLib)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long cfginfo = 0;
|
||||
int textureSize = 0;
|
||||
MTLRenderQueue rq = MTLRenderQueue.getInstance();
|
||||
rq.lock();
|
||||
try {
|
||||
int res = tryLoadMetalLibrary(displayID, mtlShadersLib);
|
||||
if (res != LOAD_LIB_OK) {
|
||||
errorMessage.append(" Cannot load metal library: " +
|
||||
switch (res) {
|
||||
case LOAD_LIB_ERROR -> "Unexpected error.";
|
||||
case LOAD_LIB_NO_DEVICE -> "No MTLDevice.";
|
||||
case LOAD_LIB_NO_SHADER_LIB -> "No Metal shader library.";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + res);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
cfginfo = getMTLConfigInfo(displayID, mtlShadersLib);
|
||||
if (cfginfo != 0L) {
|
||||
textureSize = nativeGetMaxTextureSize();
|
||||
@@ -160,6 +174,7 @@ public final class MTLGraphicsConfig extends CGraphicsConfig
|
||||
rq.unlock();
|
||||
}
|
||||
if (cfginfo == 0) {
|
||||
errorMessage.append(" Cannot create MTLConfigInfo.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ public class CPlatformView extends CFRetainedResource {
|
||||
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
logger.fine("Changed backing properties, scale = " + scale);
|
||||
}
|
||||
if (scale > 0) {
|
||||
if (scale > 0 && windowLayer != null) {
|
||||
windowLayer.replaceSurfaceData(Math.round(scale));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
private static native void nativeRaiseLevel(long nsWindowPtr, boolean popup, boolean onlyIfParentIsActive);
|
||||
private static native void nativeSetTransparentTitleBarHeight(long nsWindowPtr, float height);
|
||||
private static native void nativeCallDeliverMoveResizeEvent(long nsWindowPtr);
|
||||
private static native void nativeSetRoundedCorners(long nsWindowPrt, float radius);
|
||||
private static native void nativeSetRoundedCorners(long nsWindowPrt, float radius, int borderWidth, int borderColor);
|
||||
|
||||
// Loger to report issues happened during execution but that do not affect functionality
|
||||
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
|
||||
@@ -1531,7 +1531,13 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
|
||||
private void setRoundedCorners(Object params) {
|
||||
if (params instanceof Float) {
|
||||
execute(ptr -> nativeSetRoundedCorners(ptr, (float) params));
|
||||
execute(ptr -> nativeSetRoundedCorners(ptr, (float) params, 0, 0));
|
||||
} else if (params instanceof Object[]) {
|
||||
Object[] values = (Object[]) params;
|
||||
if (values.length == 3 && values[0] instanceof Float && values[1] instanceof Integer && values[2] instanceof Color) {
|
||||
Color color = (Color) values[2];
|
||||
execute(ptr -> nativeSetRoundedCorners(ptr, (float) values[0], (int) values[1], color.getRGB()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1519,6 +1519,9 @@ static jclass jc_CInputMethod = NULL;
|
||||
|
||||
- (void)viewDidChangeBackingProperties {
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
if ((*env)->IsSameObject(env, m_cPlatformView, NULL)) {
|
||||
return;
|
||||
}
|
||||
static double debugScale = -2.0;
|
||||
if (debugScale == -2.0) { // default debugScale value in SGE is -1.0
|
||||
debugScale = JNU_CallStaticMethodByName(env, NULL, "sun/java2d/SunGraphicsEnvironment",
|
||||
|
||||
@@ -1553,7 +1553,11 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
|
||||
} else {
|
||||
jint hitSpot = [self hitTestCustomDecoration:event.locationInWindow];
|
||||
if (event.clickCount == 2 && hitSpot == java_awt_Window_CustomWindowDecoration_NO_HIT_SPOT) {
|
||||
[self.window performZoom:nil];
|
||||
if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AppleActionOnDoubleClick"] isEqualToString:@"Maximize"]) {
|
||||
[self.window performZoom:nil];
|
||||
} else {
|
||||
[self.window performMiniaturize:nil];
|
||||
}
|
||||
}
|
||||
|
||||
// We don't follow the regular responder chain here since the native window swallows events in some cases
|
||||
@@ -2391,7 +2395,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCallDeliverMo
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetRoundedCorners
|
||||
(JNIEnv *env, jclass clazz, jlong windowPtr, jfloat radius)
|
||||
(JNIEnv *env, jclass clazz, jlong windowPtr, jfloat radius, jint borderWidth, jint borderRgb)
|
||||
{
|
||||
JNI_COCOA_ENTER(env);
|
||||
|
||||
@@ -2401,6 +2405,18 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetRoundedCor
|
||||
w.contentView.wantsLayer = YES;
|
||||
w.contentView.layer.cornerRadius = radius;
|
||||
w.contentView.layer.masksToBounds = YES;
|
||||
|
||||
if (borderWidth > 0) {
|
||||
CGFloat alpha = (((borderRgb >> 24) & 0xff) / 255.0);
|
||||
CGFloat red = (((borderRgb >> 16) & 0xff) / 255.0);
|
||||
CGFloat green = (((borderRgb >> 8) & 0xff) / 255.0);
|
||||
CGFloat blue = (((borderRgb >> 0) & 0xff) / 255.0);
|
||||
NSColor *color = [NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha];
|
||||
|
||||
w.contentView.layer.borderWidth = borderWidth;
|
||||
w.contentView.layer.borderColor = color.CGColor;
|
||||
}
|
||||
|
||||
w.backgroundColor = NSColor.clearColor;
|
||||
w.opaque = NO;
|
||||
// remove corner radius animation
|
||||
|
||||
@@ -70,11 +70,11 @@ Java_sun_java2d_metal_MTLGraphicsConfig_isMetalFrameworkAvailable
|
||||
return metalSupported;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_java2d_metal_MTLGraphicsConfig_tryLoadMetalLibrary
|
||||
(JNIEnv *env, jclass mtlgc, jint displayID, jstring shadersLibName)
|
||||
{
|
||||
__block jboolean ret = JNI_FALSE;
|
||||
__block jint ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_ERROR;
|
||||
|
||||
JNI_COCOA_ENTER(env);
|
||||
|
||||
@@ -87,12 +87,14 @@ JNI_COCOA_ENTER(env);
|
||||
NSError* error = nil;
|
||||
id<MTLLibrary> lib = [device newLibraryWithFile:path error:&error];
|
||||
if (lib != nil) {
|
||||
ret = JNI_TRUE;
|
||||
ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_OK;
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_tryLoadMetalLibrary - Failed to load Metal shader library.");
|
||||
ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_NO_SHADER_LIB;
|
||||
}
|
||||
} else {
|
||||
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_tryLoadMetalLibrary - Failed to create MTLDevice.");
|
||||
ret = sun_java2d_metal_MTLGraphicsConfig_LOAD_LIB_NO_DEVICE;
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
@@ -152,17 +152,6 @@ public abstract class KeyboardFocusManager
|
||||
public Container getCurrentFocusCycleRoot() {
|
||||
return KeyboardFocusManager.currentFocusCycleRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueueKeyEvents(Component untilFocused) {
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().enqueueKeyEvents(
|
||||
Toolkit.getEventQueue().getMostRecentKeyEventTime(), untilFocused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dequeueKeyEvents(Component untilFocused) {
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().dequeueKeyEvents(-1, untilFocused);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -464,10 +464,6 @@ public final class AWTAccessor {
|
||||
* Return the current focus cycle root
|
||||
*/
|
||||
Container getCurrentFocusCycleRoot();
|
||||
|
||||
void enqueueKeyEvents(Component untilFocused);
|
||||
|
||||
void dequeueKeyEvents(Component untilFocused);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, JetBrains s.r.o.. 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.awt;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
public interface DisplayParametersChangedListener extends EventListener {
|
||||
/**
|
||||
* Invoked when the display parameters changed.
|
||||
*/
|
||||
public void displayParametersChanged();
|
||||
}
|
||||
@@ -50,6 +50,7 @@ import java.util.Locale;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import sun.awt.DisplayChangedListener;
|
||||
import sun.awt.DisplayParametersChangedListener;
|
||||
import sun.awt.SunDisplayChanger;
|
||||
import sun.font.*;
|
||||
import sun.java2d.pipe.Region;
|
||||
@@ -64,7 +65,7 @@ import sun.security.action.GetPropertyAction;
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
|
||||
implements DisplayChangedListener {
|
||||
implements DisplayChangedListener, DisplayParametersChangedListener {
|
||||
|
||||
/** Establish the default font to be used by SG2D. */
|
||||
private final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||
@@ -271,6 +272,15 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
|
||||
displayChanger.notifyListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayParametersChanged() {
|
||||
for (GraphicsDevice gd : getScreenDevices()) {
|
||||
if (gd instanceof DisplayParametersChangedListener) {
|
||||
((DisplayParametersChangedListener) gd).displayParametersChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the DisplayChangedListener interface:
|
||||
* propagate this event to listeners
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2022, 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
|
||||
@@ -25,68 +25,44 @@
|
||||
|
||||
package sun.java2d.loops;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class RenderCache {
|
||||
final class Entry {
|
||||
private SurfaceType src;
|
||||
private CompositeType comp;
|
||||
private SurfaceType dst;
|
||||
private Object value;
|
||||
private final int MAX_ENTRIES;
|
||||
private final Map<Key, Object> mruCache;
|
||||
|
||||
public Entry(SurfaceType src,
|
||||
CompositeType comp,
|
||||
SurfaceType dst,
|
||||
Object value)
|
||||
{
|
||||
this.src = src;
|
||||
this.comp = comp;
|
||||
this.dst = dst;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean matches(SurfaceType src,
|
||||
CompositeType comp,
|
||||
SurfaceType dst)
|
||||
{
|
||||
// bug 4725045: using equals() causes different SurfaceType
|
||||
// objects with the same strings to match in the cache, which is
|
||||
// not the behavior we want. Constrain the match to succeed only
|
||||
// on object matches instead.
|
||||
return ((this.src == src) &&
|
||||
(this.comp == comp) &&
|
||||
(this.dst == dst));
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
record Key(SurfaceType src, CompositeType comp, SurfaceType dst) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Key other) {
|
||||
// bug 4725045: using equals() causes different SurfaceType
|
||||
// objects with the same strings to match in the cache, which is
|
||||
// not the behavior we want. Constrain the match to succeed only
|
||||
// on object matches instead.
|
||||
return ((this.src == other.src) &&
|
||||
(this.comp == other.comp) &&
|
||||
(this.dst == other.dst));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Entry[] entries;
|
||||
|
||||
public RenderCache(int size) {
|
||||
entries = new Entry[size];
|
||||
MAX_ENTRIES = size;
|
||||
mruCache = new LinkedHashMap<>(size + 1) {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Key, Object> eldest) {
|
||||
return size() > MAX_ENTRIES;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public synchronized Object get(SurfaceType src,
|
||||
CompositeType comp,
|
||||
SurfaceType dst)
|
||||
{
|
||||
int max = entries.length - 1;
|
||||
for (int i = max; i >= 0; i--) {
|
||||
Entry e = entries[i];
|
||||
if (e == null) {
|
||||
break;
|
||||
}
|
||||
if (e.matches(src, comp, dst)) {
|
||||
if (i < max - 4) {
|
||||
System.arraycopy(entries, i+1, entries, i, max - i);
|
||||
entries[max] = e;
|
||||
}
|
||||
return e.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return mruCache.get(new Key(src, comp, dst));
|
||||
}
|
||||
|
||||
public synchronized void put(SurfaceType src,
|
||||
@@ -94,10 +70,6 @@ public final class RenderCache {
|
||||
SurfaceType dst,
|
||||
Object value)
|
||||
{
|
||||
Entry e = new Entry(src, comp, dst, value);
|
||||
|
||||
int num = entries.length;
|
||||
System.arraycopy(entries, 1, entries, 0, num - 1);
|
||||
entries[num - 1] = e;
|
||||
mruCache.put(new Key(src, comp, dst), value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,15 +293,21 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
||||
* when a component inside a Frame is requesting focus.
|
||||
* See 6314575 for details.
|
||||
*/
|
||||
return wpeer.requestWindowFocus(null, () -> {
|
||||
XKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
|
||||
target,
|
||||
temporary,
|
||||
focusedWindowChangeAllowed,
|
||||
time, cause);
|
||||
}, () -> {
|
||||
rejectFocusRequestHelper("Waiting for asynchronous processing of the request");
|
||||
});
|
||||
boolean res = wpeer.requestWindowFocus(null);
|
||||
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
|
||||
focusLog.finer("Requested window focus: " + res);
|
||||
}
|
||||
// If parent window can be made focused and has been made focused(synchronously)
|
||||
// then we can proceed with children, otherwise we retreat.
|
||||
if (!(res && parentWindow.isFocused())) {
|
||||
return rejectFocusRequestHelper("Waiting for asynchronous processing of the request");
|
||||
}
|
||||
return XKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
|
||||
target,
|
||||
temporary,
|
||||
focusedWindowChangeAllowed,
|
||||
time, cause);
|
||||
// Motif compatibility code
|
||||
case XKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
|
||||
// Either lightweight or excessive request - all events are generated.
|
||||
|
||||
@@ -1258,7 +1258,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
|
||||
if (target == activeWindow && target != focusedWindow) {
|
||||
// Happens when an owned window is currently focused
|
||||
focusLog.fine("Focus is on child window - transferring it back to the owner");
|
||||
handleWindowFocusInSync(-1, () -> {});
|
||||
handleWindowFocusInSync(-1);
|
||||
return true;
|
||||
}
|
||||
Window realNativeFocusedWindow = XWindowPeer.getNativeFocusedWindow();
|
||||
|
||||
@@ -424,14 +424,13 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void sendEvent(final AWTEvent e, Runnable lightweigtRequestRunnable) {
|
||||
static void sendEvent(final AWTEvent e) {
|
||||
// The uses of this method imply that the incoming event is system-generated
|
||||
SunToolkit.setSystemGenerated(e);
|
||||
PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
|
||||
public void run() {
|
||||
AWTAccessor.getAWTEventAccessor().setPosted(e);
|
||||
((Component)e.getSource()).dispatchEvent(e);
|
||||
lightweigtRequestRunnable.run();
|
||||
}
|
||||
}, PeerEvent.ULTIMATE_PRIORITY_EVENT);
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINER) && (e instanceof FocusEvent)) {
|
||||
@@ -440,9 +439,6 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
|
||||
XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), pe);
|
||||
}
|
||||
|
||||
static void sendEvent(final AWTEvent e) {
|
||||
sendEvent(e, () -> {});
|
||||
}
|
||||
|
||||
/*
|
||||
* Post an event to the event queue.
|
||||
|
||||
@@ -618,15 +618,16 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
target.dispatchEvent(we);
|
||||
}
|
||||
}
|
||||
public void handleWindowFocusInSync(long serial, Runnable lightweigtRequest) {
|
||||
|
||||
public void handleWindowFocusInSync(long serial) {
|
||||
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
|
||||
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
|
||||
sendEvent(we, lightweigtRequest);
|
||||
sendEvent(we);
|
||||
}
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
public void handleWindowFocusIn(long serial) {
|
||||
handleWindowFocusInSync(serial, () -> {});
|
||||
handleWindowFocusInSync(serial);
|
||||
}
|
||||
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
@@ -847,16 +848,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
focusLog.fine("Requesting window focus");
|
||||
}
|
||||
Runnable finishRunnable = this::dequeueKeyEvents;
|
||||
requestWindowFocus(time, timeProvided, finishRunnable, finishRunnable);
|
||||
}
|
||||
|
||||
private void dequeueKeyEvents() {
|
||||
AWTAccessor.getKeyboardFocusManagerAccessor().dequeueKeyEvents(target);
|
||||
}
|
||||
|
||||
private void enqueueKeyEvents() {
|
||||
AWTAccessor.getKeyboardFocusManagerAccessor().enqueueKeyEvents(target);
|
||||
requestWindowFocus(time, timeProvided);
|
||||
}
|
||||
|
||||
public final boolean focusAllowedFor() {
|
||||
@@ -1144,17 +1136,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
warningWindow.setSecurityWarningVisible(false, false);
|
||||
}
|
||||
boolean refreshChildsTransientFor = isVisible() != vis;
|
||||
// To enable type-ahead for 'simple' windows, we initiate internal focus transfer to such a window even before
|
||||
// it's mapped by a window manager. 'Simple' windows aren't natively focusable, so for this to work as expected
|
||||
// we only need to be sure that the window will be mapped soon after we request it. There are known cases when
|
||||
// window manager delays mapping the window for a long time (e.g. i3wm does this when another window is in
|
||||
// full-screen mode), but no known cases when it does it for popup windows, so we hope that we're safe here with
|
||||
// 'simple' windows.
|
||||
if (vis && isSimpleWindow() && shouldFocusOnMapNotify()) {
|
||||
// We enable type-ahead mechanism only for showing of simple windows. That's because, when enabling it,
|
||||
// we need to be sure that the final state (focusing) of the target window will definitely be available
|
||||
// very soon, not to block key events for a long period of time. As simple windows are not focused natively,
|
||||
// the only event we should wait for before focusing them internally is MapNotify, and that event usually
|
||||
// comes quite fast after map request. There are known cases when window manager delays mapping the window
|
||||
// for a long time (e.g. i3wm does this when another window is in full-screen mode), but no known cases
|
||||
// when it does it for popup windows, so we hope that we're safe here with simple windows. For decorated
|
||||
// windows we also wait for the native focus to be transferred to the target window (FocusIn event),
|
||||
// which adds to the uncertainty - the focus might or might not be transferred.
|
||||
enqueueKeyEvents();
|
||||
requestInitialFocus();
|
||||
}
|
||||
super.setVisible(vis);
|
||||
if (refreshChildsTransientFor) {
|
||||
@@ -1223,7 +1212,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
if (targetOwner != null) {
|
||||
XWindowPeer xwndpeer = AWTAccessor.getComponentAccessor().getPeer(targetOwner);
|
||||
if (xwndpeer != null) {
|
||||
xwndpeer.requestWindowFocus(() -> {}, () -> {});
|
||||
xwndpeer.requestWindowFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1495,15 +1484,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shouldFocusOnMapNotify()) {
|
||||
if (!isSimpleWindow() && shouldFocusOnMapNotify() && !XWM.isWeston()) {
|
||||
focusLog.fine("Automatically request focus on window");
|
||||
if (XWM.isWeston()) {
|
||||
requestInitialFocusInternally();
|
||||
} else {
|
||||
requestInitialFocus();
|
||||
}
|
||||
} else {
|
||||
dequeueKeyEvents();
|
||||
requestInitialFocus();
|
||||
}
|
||||
isUnhiding = false;
|
||||
isBeforeFirstMapNotify = false;
|
||||
@@ -1555,18 +1538,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
requestXFocus();
|
||||
}
|
||||
|
||||
// This will request focus without sending any requests to X server or window manager.
|
||||
// It can only work for 'simple' windows, as their focusing is managed internally
|
||||
// (natively, simple window's owner is seen as focused window).
|
||||
private void requestInitialFocusInternally() {
|
||||
if (isSimpleWindow() &&
|
||||
XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner() == getDecoratedOwner((Window)target)) {
|
||||
handleWindowFocusInSync(-1, this::dequeueKeyEvents);
|
||||
} else {
|
||||
dequeueKeyEvents();
|
||||
}
|
||||
}
|
||||
|
||||
public void addToplevelStateListener(ToplevelStateListener l){
|
||||
toplevelStateListeners.add(l);
|
||||
}
|
||||
@@ -2067,25 +2038,16 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
return window;
|
||||
}
|
||||
|
||||
public boolean requestWindowFocus(XWindowPeer actualFocusedWindow, Runnable lightweigtRequest, Runnable rejectFocusRequest) {
|
||||
public boolean requestWindowFocus(XWindowPeer actualFocusedWindow) {
|
||||
setActualFocusedWindow(actualFocusedWindow);
|
||||
return requestWindowFocus(lightweigtRequest, rejectFocusRequest);
|
||||
return requestWindowFocus();
|
||||
}
|
||||
|
||||
public boolean requestWindowFocus() {
|
||||
return requestWindowFocus(() -> {}, () -> {});
|
||||
}
|
||||
|
||||
public boolean requestWindowFocus(Runnable lightweigtRequest, Runnable rejectFocusRequest) {
|
||||
return requestWindowFocus(0, false, lightweigtRequest, rejectFocusRequest);
|
||||
return requestWindowFocus(0, false);
|
||||
}
|
||||
|
||||
public boolean requestWindowFocus(long time, boolean timeProvided) {
|
||||
return requestWindowFocus(time, timeProvided, () -> {}, () -> {});
|
||||
}
|
||||
|
||||
public boolean requestWindowFocus(long time, boolean timeProvided,
|
||||
Runnable lightweigtRequest, Runnable rejectFocusRequest) {
|
||||
focusLog.fine("Request for window focus");
|
||||
// If this is Frame or Dialog we can't assure focus request success - but we still can try
|
||||
// If this is Window and its owner Frame is active we can be sure request succedded.
|
||||
@@ -2095,12 +2057,11 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
|
||||
if (isWMStateNetHidden()) {
|
||||
focusLog.fine("The window is unmapped, so rejecting the request");
|
||||
rejectFocusRequest.run();
|
||||
return false;
|
||||
}
|
||||
if (activeWindow == ownerWindow) {
|
||||
focusLog.fine("Parent window is active - generating focus for this window");
|
||||
handleWindowFocusInSync(-1, lightweigtRequest);
|
||||
handleWindowFocusInSync(-1);
|
||||
return true;
|
||||
}
|
||||
focusLog.fine("Parent window is not active");
|
||||
@@ -2108,11 +2069,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
||||
XDecoratedPeer wpeer = AWTAccessor.getComponentAccessor().getPeer(ownerWindow);
|
||||
if (wpeer != null && wpeer.requestWindowFocus(this, time, timeProvided)) {
|
||||
focusLog.fine("Parent window accepted focus request - generating focus for this window");
|
||||
handleWindowFocusInSync(-1, lightweigtRequest);
|
||||
return true;
|
||||
}
|
||||
focusLog.fine("Denied - parent window is not active and didn't accept focus request");
|
||||
rejectFocusRequest.run();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.awt.Window;
|
||||
*/
|
||||
public interface RoundedCornersManager {
|
||||
/**
|
||||
* @param params for macOS is Float object with radius.
|
||||
* @param params for macOS is Float object with radius or
|
||||
* Array with {Float for radius, Integer for border width, java.awt.Color for border color}.
|
||||
*
|
||||
* @param params for Windows 11 is String with values:
|
||||
* "default" - let the system decide whether or not to round window corners,
|
||||
|
||||
119
test/jdk/java/awt/Dialog/CloseDialog/CloseDialogTest.java
Normal file
119
test/jdk/java/awt/Dialog/CloseDialog/CloseDialogTest.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2017, 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.
|
||||
*/
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.io.*;
|
||||
import javax.swing.*;
|
||||
import sun.awt.SunToolkit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8043705
|
||||
* @summary Can't exit color chooser dialog when running as an applet
|
||||
* @modules java.desktop/sun.awt
|
||||
* @run main CloseDialogTest
|
||||
*/
|
||||
|
||||
public class CloseDialogTest {
|
||||
|
||||
private static volatile Frame frame;
|
||||
private static volatile Dialog dialog;
|
||||
private static volatile InputStream testErrorStream;
|
||||
private static final PrintStream systemErrStream = System.err;
|
||||
private static final AtomicReference<Exception> caughtException
|
||||
= new AtomicReference<>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// redirect System err
|
||||
PipedOutputStream errorOutputStream = new PipedOutputStream();
|
||||
testErrorStream = new PipedInputStream(errorOutputStream);
|
||||
System.setErr(new PrintStream(errorOutputStream));
|
||||
|
||||
ThreadGroup swingTG = new ThreadGroup(getRootThreadGroup(), "SwingTG");
|
||||
try {
|
||||
new Thread(swingTG, () -> {
|
||||
SunToolkit.createNewAppContext();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
frame = new Frame();
|
||||
frame.setSize(300, 300);
|
||||
frame.setVisible(true);
|
||||
|
||||
dialog = new Dialog(frame);
|
||||
dialog.setSize(200, 200);
|
||||
dialog.setModal(true);
|
||||
dialog.setVisible(true);
|
||||
});
|
||||
}).start();
|
||||
|
||||
Thread.sleep(400);
|
||||
|
||||
Thread disposeThread = new Thread(swingTG, () ->
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
while (dialog == null || !dialog.isVisible()) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
dialog.setVisible(false);
|
||||
dialog.dispose();
|
||||
frame.dispose();
|
||||
} catch (Exception e) {
|
||||
caughtException.set(e);
|
||||
}
|
||||
}));
|
||||
disposeThread.start();
|
||||
disposeThread.join();
|
||||
Thread.sleep(500);
|
||||
|
||||
// read System err
|
||||
final char[] buffer = new char[2048];
|
||||
System.err.print("END");
|
||||
System.setErr(systemErrStream);
|
||||
try (Reader in = new InputStreamReader(testErrorStream, "UTF-8")) {
|
||||
int size = in.read(buffer, 0, buffer.length);
|
||||
String errorString = new String(buffer, 0, size);
|
||||
if (!errorString.startsWith("END")) {
|
||||
System.err.println(errorString.
|
||||
substring(0, errorString.length() - 4));
|
||||
throw new RuntimeException("Error output is not empty!");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (caughtException.get() != null) {
|
||||
throw new RuntimeException("Failed. Caught exception!",
|
||||
caughtException.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ThreadGroup getRootThreadGroup() {
|
||||
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
|
||||
while (threadGroup.getParent() != null) {
|
||||
threadGroup = threadGroup.getParent();
|
||||
}
|
||||
return threadGroup;
|
||||
}
|
||||
}
|
||||
104
test/jdk/jb/java/api/frontend/CustomTitleBarDoubleClick.java
Normal file
104
test/jdk/jb/java/api/frontend/CustomTitleBarDoubleClick.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2000-2021 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test
|
||||
@requires os.family == "mac" | os.family == "windows"
|
||||
@key headful
|
||||
@summary Test that window state changes on titlebar double-click
|
||||
@library ../../../../java/awt/regtesthelpers
|
||||
@build Util
|
||||
@run shell build.sh
|
||||
@run main CustomTitleBarDoubleClick
|
||||
*/
|
||||
|
||||
import com.jetbrains.JBR;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import test.java.awt.regtesthelpers.Util;
|
||||
|
||||
public class CustomTitleBarDoubleClick implements WindowListener, WindowStateListener {
|
||||
//Declare things used in the test, like buttons and labels here
|
||||
private final static Rectangle BOUNDS = new Rectangle(300, 300, 300, 300);
|
||||
private final static int TITLE_BAR_OFFSET = 10;
|
||||
|
||||
JFrame frame;
|
||||
Robot robot;
|
||||
boolean stateChanged;
|
||||
|
||||
public static void main(final String[] args) {
|
||||
CustomTitleBarDoubleClick app = new CustomTitleBarDoubleClick();
|
||||
app.start();
|
||||
}
|
||||
|
||||
public void start () {
|
||||
robot = Util.createRobot();
|
||||
robot.setAutoDelay(100);
|
||||
robot.mouseMove(BOUNDS.x + (BOUNDS.width / 2),
|
||||
BOUNDS.y + (BOUNDS.height/ 2));
|
||||
|
||||
frame = new JFrame("CustomTitleBarDoubleClick"); // Custom decorations doesn't work for AWT Frames on macOS
|
||||
frame.setBounds(BOUNDS);
|
||||
frame.addWindowListener(this);
|
||||
frame.addWindowStateListener(this);
|
||||
JBR.getCustomWindowDecoration().setCustomDecorationEnabled(frame, true);
|
||||
JBR.getCustomWindowDecoration().setCustomDecorationTitleBarHeight(frame, 50);
|
||||
frame.setVisible(true);
|
||||
robot.delay(2000);
|
||||
if (!stateChanged) throw new AWTError("Test failed");
|
||||
}
|
||||
|
||||
// Move the mouse into the title bar and double click to maximize the Frame
|
||||
static boolean hasRun = false;
|
||||
|
||||
private void doTest() {
|
||||
if (hasRun) return;
|
||||
hasRun = true;
|
||||
|
||||
System.out.println("doing test");
|
||||
robot.mouseMove(BOUNDS.x + (BOUNDS.width / 2),
|
||||
BOUNDS.y + TITLE_BAR_OFFSET);
|
||||
robot.delay(50);
|
||||
// Util.waitForIdle(robot) seem always hangs here.
|
||||
// Need to use it instead robot.delay() when the bug become fixed.
|
||||
System.out.println("1st press: currentTimeMillis: " + System.currentTimeMillis());
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(50);
|
||||
System.out.println("1st release: currentTimeMillis: " + System.currentTimeMillis());
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(50);
|
||||
System.out.println("2nd press: currentTimeMillis: " + System.currentTimeMillis());
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(50);
|
||||
System.out.println("2nd release: currentTimeMillis: " + System.currentTimeMillis());
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
System.out.println("done: currentTimeMillis: " + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void windowActivated(WindowEvent e) {doTest();}
|
||||
public void windowClosed(WindowEvent e) {}
|
||||
public void windowClosing(WindowEvent e) {}
|
||||
public void windowDeactivated(WindowEvent e) {}
|
||||
public void windowDeiconified(WindowEvent e) {}
|
||||
public void windowIconified(WindowEvent e) {}
|
||||
public void windowOpened(WindowEvent e) {}
|
||||
|
||||
public void windowStateChanged(WindowEvent e) {
|
||||
stateChanged = true; // On macOS double-click may cause window to be maximized or iconified depending on AppleActionOnDoubleClick setting
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,6 +50,8 @@ public class JBRApiTest {
|
||||
private static void testServices() {
|
||||
Objects.requireNonNull(JBR.getExtendedGlyphCache().getSubpixelResolution());
|
||||
Objects.requireNonNull(JBRFileDialog.get(new FileDialog((Frame) null)));
|
||||
Objects.requireNonNull(JBR.getRoundedCornersManager());
|
||||
if (!System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
Objects.requireNonNull(JBR.getRoundedCornersManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
104
test/jdk/jb/java/awt/Focus/ContextMenuAfterPopup.java
Normal file
104
test/jdk/jb/java/awt/Focus/ContextMenuAfterPopup.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2022 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Regression test for JBR-4820 Focus lost after showing popup and context menu
|
||||
* @key headful
|
||||
*/
|
||||
|
||||
public class ContextMenuAfterPopup {
|
||||
private static Robot robot;
|
||||
private static JFrame frame;
|
||||
private static JTextField frameField;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
robot.setAutoDelay(50);
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(ContextMenuAfterPopup::initUI);
|
||||
robot.delay(1000);
|
||||
clickOn(frameField);
|
||||
robot.delay(1000);
|
||||
type(KeyEvent.VK_ENTER);
|
||||
robot.delay(1000);
|
||||
type(KeyEvent.VK_SPACE);
|
||||
robot.delay(1000);
|
||||
type(KeyEvent.VK_ESCAPE);
|
||||
robot.delay(1000);
|
||||
type(KeyEvent.VK_A);
|
||||
robot.delay(1000);
|
||||
if (!"a".equals(frameField.getText())) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} finally {
|
||||
SwingUtilities.invokeAndWait(ContextMenuAfterPopup::disposeUI);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initUI() {
|
||||
frame = new JFrame("ContextMenuAfterPopup");
|
||||
frameField = new JTextField(30);
|
||||
frameField.addActionListener(e -> {
|
||||
JWindow popup = new JWindow(frame);
|
||||
JButton b = new JButton("Show context menu");
|
||||
b.addActionListener(ee -> {
|
||||
popup.dispose();
|
||||
JPopupMenu pm = new JPopupMenu();
|
||||
pm.add("item 1");
|
||||
pm.add("item 2");
|
||||
pm.show(frameField, 20, 20);
|
||||
});
|
||||
popup.add(b);
|
||||
popup.pack();
|
||||
popup.setVisible(true);
|
||||
});
|
||||
frame.add(frameField);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private static void disposeUI() {
|
||||
if (frame != null) frame.dispose();
|
||||
}
|
||||
|
||||
private static void type(int keyCode) {
|
||||
robot.keyPress(keyCode);
|
||||
robot.keyRelease(keyCode);
|
||||
}
|
||||
|
||||
private static void clickAt(int x, int y) {
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
}
|
||||
|
||||
private static void clickOn(Component component) {
|
||||
Point location = component.getLocationOnScreen();
|
||||
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
|
||||
}
|
||||
}
|
||||
@@ -406,7 +406,7 @@ java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFModeless3Test.java 825318
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal1Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal2Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalFocusTransferTests/FocusTransferWDFNonModal3Test.java 8253184 windows-all
|
||||
java/awt/Modal/ModalInternalFrameTest/ModalInternalFrameTest.java 8253184 windows-all
|
||||
java/awt/Modal/ModalInternalFrameTest/ModalInternalFrameTest.java 8253184,8159599 windows-all,linux-all #8253184 windows-all; 8159599 linux-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs1Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs2Test.java 8198665 macosx-all
|
||||
java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java 8198665 macosx-all
|
||||
@@ -918,12 +918,13 @@ javax/swing/JList/6462008/bug6462008.java
|
||||
javax/swing/JMenu/6470128/bug6470128.java nobug windows-all
|
||||
|
||||
# no printer found
|
||||
java/awt/print/PrinterJob/CheckPrivilege.java nobug generic-all
|
||||
java/awt/print/PrinterJob/CheckPrivilege.java JBR-893 generic-all
|
||||
java/awt/print/PrinterJob/ExceptionTest.java nobug generic-all
|
||||
java/awt/print/PrinterJob/ExceptionFromPrintableIsIgnoredTest.java nobug generic-all
|
||||
java/awt/print/PrinterJob/ImagePrinting/NullClipARGB.java nobug generic-all
|
||||
java/awt/print/PrinterJob/LandscapeStackOverflow.java nobug generic-all
|
||||
java/awt/print/PrinterJob/PaintText.java nobug generic-all
|
||||
java/awt/print/PrinterJob/LandscapeStackOverflow.java JBR-893 generic-all
|
||||
java/awt/print/PrinterJob/Margins.java JBR-893 generic-all
|
||||
java/awt/print/PrinterJob/PaintText.java JBR-893 generic-all
|
||||
java/awt/print/PrinterJob/PrintCrashTest.java nobug generic-all
|
||||
java/awt/print/PrinterJob/PrtException.java nobug generic-all
|
||||
javax/print/attribute/ChromaticityValues.java nobug generic-all
|
||||
|
||||
Reference in New Issue
Block a user