JBR-4834 JBR-5139 Rounded corners on Mac OS and Windows: support custom border color

This commit is contained in:
Alexander Lobas
2022-09-16 11:21:35 +03:00
committed by Nikita Gubarkov
parent 0b777f2360
commit 54f70cfc23
6 changed files with 59 additions and 17 deletions

View File

@@ -109,7 +109,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native boolean nativeDelayShowing(long nsWindowPtr);
private static native void nativeUpdateCustomTitleBar(long nsWindowPtr);
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);
// Logger to report issues happened during execution but that do not affect functionality
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
@@ -1500,7 +1500,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()));
}
}
}
}

View File

@@ -2593,7 +2593,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);
@@ -2603,6 +2603,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

View File

@@ -846,19 +846,30 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
private void setRoundedCornersImpl(Object params) {
if (params instanceof String) {
int type = 0; // default
if ("none".equals(params)) {
type = 1;
} else if ("full".equals(params)) {
type = 2;
} else if ("small".equals(params)) {
type = 3;
setRoundedCorners(getRoundedType(params), false, 0);
} else if (params instanceof Object[]) {
Object[] values = (Object[]) params;
if (values.length == 2 && values[0] instanceof String && values[1] instanceof Color) {
Color color = (Color) values[1];
setRoundedCorners(getRoundedType(values[0]), true, color.getRGB());
}
setRoundedCorners(type);
}
}
private native void setRoundedCorners(int type);
private static int getRoundedType(Object params) {
if ("none".equals(params)) {
return 1;
}
if ("full".equals(params)) {
return 2;
}
if ("small".equals(params)) {
return 3;
}
return 0; // default
}
private native void setRoundedCorners(int type, boolean isBorderColor, int borderColor);
native void updateWindowImpl(int[] data, int width, int height);

View File

@@ -54,6 +54,7 @@ typedef __int32 LONG_PTR;
// Define these to be able to build with older SDKs
#define DWM_WINDOW_CORNER_PREFERENCE int
#define DWMWA_WINDOW_CORNER_PREFERENCE 33
#define DWMWA_BORDER_COLOR 34
// Used for Swing's Menu/Tooltip animation Support
const int UNSPECIFIED = 0;
@@ -134,6 +135,8 @@ struct OpaqueStruct {
struct RoundedCornersStruct {
jobject window;
DWM_WINDOW_CORNER_PREFERENCE type;
jboolean isBorderColor;
jint borderColor;
};
// struct for _UpdateWindow() method
struct UpdateWindowStruct {
@@ -3397,6 +3400,13 @@ void AwtWindow::_SetRoundedCorners(void *param) {
DwmSetWindowAttribute(window->GetHWnd(), DWMWA_WINDOW_CORNER_PREFERENCE, &rcs->type, sizeof(DWM_WINDOW_CORNER_PREFERENCE));
if (rcs->isBorderColor) {
jint red = (rcs->borderColor >> 16) & 0xff;
jint green = (rcs->borderColor >> 8) & 0xff;
jint blue = (rcs->borderColor >> 0) & 0xff;
COLORREF borderColor = RGB(red, green, blue);
DwmSetWindowAttribute(window->GetHWnd(), DWMWA_BORDER_COLOR, &borderColor, sizeof(COLORREF));
}
ret:
env->DeleteGlobalRef(self);
delete rcs;
@@ -4171,16 +4181,18 @@ Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env,
/*
* Class: sun_awt_windows_WWindowPeer
* Method: setRoundedCorners
* Signature: (I)V
* Signature: (IZI)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WWindowPeer_setRoundedCorners(JNIEnv *env, jobject self, jint type)
Java_sun_awt_windows_WWindowPeer_setRoundedCorners(JNIEnv *env, jobject self, jint type, jboolean isBorderColor, jint borderColor)
{
TRY;
RoundedCornersStruct *rcs = new RoundedCornersStruct;
rcs->window = env->NewGlobalRef(self);
rcs->type = (DWM_WINDOW_CORNER_PREFERENCE)type;
rcs->isBorderColor = isBorderColor;
rcs->borderColor = borderColor;
AwtToolkit::GetInstance().SyncCall(AwtWindow::_SetRoundedCorners, rcs);
// global refs and rcs are deleted in _SetRoundedCorners

View File

@@ -33,7 +33,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,

View File

@@ -6,9 +6,9 @@
# 2. When only new API is added, or some existing API was @Deprecated - increment MINOR, reset PATCH to 0
# 3. For major backwards incompatible API changes - increment MAJOR, reset MINOR and PATCH to 0
VERSION = 0.0.14
VERSION = 0.0.15
# Hash is used to track changes to jetbrains.api, so you would not forget to update version when needed.
# When you make any changes, "make jbr-api" will fail and ask you to update hash and version number here.
HASH = D28F22789F62EA4F8B8F4E7EC8B342E5
HASH = 944323BE83C422C02167A3D328955130