JBR-2893 Big Sur: Add support of opening project as tabs IDEA-257932 Big Sur: IDEA hangs after closing a project tab after exiting and entering full screen

Converted JNF to JNIUtilites

(cherry picked from commit f02e31a440)
(cherry-picked from commit a84736ebcc)
This commit is contained in:
Alexander Lobas
2020-12-25 20:31:10 +03:00
committed by Alexey Ushakov
parent 67ab7032c8
commit 0cf6d2da8d
3 changed files with 155 additions and 1 deletions

View File

@@ -47,6 +47,8 @@
NSRect standardFrame;
BOOL isMinimizing;
BOOL isJustCreated;
NSWindowTabbingMode javaWindowTabbingMode;
BOOL isEnterFullScreen;
}
// An instance of either AWTWindow_Normal or AWTWindow_Panel
@@ -63,6 +65,8 @@
@property (nonatomic) NSRect standardFrame;
@property (nonatomic) BOOL isMinimizing;
@property (nonatomic) BOOL isJustCreated;
@property (nonatomic) NSWindowTabbingMode javaWindowTabbingMode;
@property (nonatomic) BOOL isEnterFullScreen;
- (id) initWithPlatformWindow:(jobject)javaPlatformWindow
ownerWindow:owner
@@ -72,6 +76,8 @@
- (BOOL) isTopmostWindowUnderMouse;
- (NSWindowTabbingMode) getJavaWindowTabbingMode;
// NSWindow overrides delegate methods
- (BOOL) canBecomeKeyWindow;
- (void) becomeKeyWindow;

View File

@@ -67,6 +67,8 @@ static AWTWindow* lastKeyWindow = nil;
// It would be NSZeroPoint if 'Location by Platform' is not used.
static NSPoint lastTopLeftPoint;
static BOOL ignoreResizeWindowDuringAnotherWindowEnd = NO;
// --------------------------------------------------------------
// NSWindow/NSPanel descendants implementation
#define AWT_NS_WINDOW_IMPLEMENTATION \
@@ -119,7 +121,7 @@ static NSPoint lastTopLeftPoint;
} \
\
- (NSWindowTabbingMode)tabbingMode { \
return NSWindowTabbingModeDisallowed; \
return ((AWTWindow*)[self delegate]).javaWindowTabbingMode; \
}
@implementation AWTWindow_Normal
@@ -229,6 +231,69 @@ AWT_NS_WINDOW_IMPLEMENTATION
b:[event deltaY]];
}
- (void)moveTabToNewWindow:(id)sender {
AWT_ASSERT_APPKIT_THREAD;
[super moveTabToNewWindow:sender];
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = (*env)->NewLocalRef(env, ((AWTWindow *)self.delegate).javaPlatformWindow);
if (platformWindow != NULL) {
// extract the target AWT Window object out of the CPlatformWindow
GET_CPLATFORM_WINDOW_CLASS();
DECLARE_FIELD(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
jobject awtWindow = (*env)->GetObjectField(env, platformWindow, jf_target);
if (awtWindow != NULL) {
DECLARE_CLASS(jc_Window, "java/awt/Window");
DECLARE_METHOD(jm_runMoveTabToNewWindowCallback, jc_Window, "runMoveTabToNewWindowCallback", "()V");
(*env)->CallVoidMethod(env, awtWindow, jm_runMoveTabToNewWindowCallback);
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, awtWindow);
}
(*env)->DeleteLocalRef(env, platformWindow);
}
#ifdef DEBUG
NSLog(@"=== Move Tab to new Window ===");
#endif
}
// Call over Foundation from Java
- (CGFloat) getTabBarVisibleAndHeight {
if (@available(macOS 10.13, *)) {
id tabGroup = [self tabGroup];
#ifdef DEBUG
NSLog(@"=== Window tabBar: %@ ===", tabGroup);
#endif
if ([tabGroup isTabBarVisible]) {
if ([tabGroup respondsToSelector:@selector(_tabBar)]) { // private member
CGFloat height = [[tabGroup _tabBar] frame].size.height;
#ifdef DEBUG
NSLog(@"=== Window tabBar visible: %f ===", height);
#endif
return height;
}
#ifdef DEBUG
NSLog(@"=== NsWindow.tabGroup._tabBar not found ===");
#endif
return -1; // if we don't get height return -1 and use default value in java without change native code
}
#ifdef DEBUG
NSLog(@"=== Window tabBar not visible ===");
#endif
} else {
#ifdef DEBUG
NSLog(@"=== Window tabGroup not supported before macOS 10.13 ===");
#endif
}
return 0;
}
- (void)orderOut:(id)sender {
ignoreResizeWindowDuringAnotherWindowEnd = YES;
[super orderOut:sender];
}
@end
@implementation AWTWindow_Panel
AWT_NS_WINDOW_IMPLEMENTATION
@@ -251,6 +316,8 @@ AWT_NS_WINDOW_IMPLEMENTATION
@synthesize standardFrame;
@synthesize isMinimizing;
@synthesize isJustCreated;
@synthesize javaWindowTabbingMode;
@synthesize isEnterFullScreen;
- (void) updateMinMaxSize:(BOOL)resizable {
if (resizable) {
@@ -401,6 +468,9 @@ AWT_ASSERT_APPKIT_THREAD;
self.isJustCreated = YES;
self.javaWindowTabbingMode = [self getJavaWindowTabbingMode];
self.isEnterFullScreen = NO;
return self;
}
@@ -418,6 +488,35 @@ AWT_ASSERT_APPKIT_THREAD;
return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
}
- (NSWindowTabbingMode) getJavaWindowTabbingMode {
AWT_ASSERT_APPKIT_THREAD;
BOOL result = NO;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow);
if (platformWindow != NULL) {
// extract the target AWT Window object out of the CPlatformWindow
GET_CPLATFORM_WINDOW_CLASS_RETURN(NSWindowTabbingModeDisallowed);
DECLARE_FIELD_RETURN(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;", NSWindowTabbingModeDisallowed);
jobject awtWindow = (*env)->GetObjectField(env, platformWindow, jf_target);
if (awtWindow != NULL) {
DECLARE_CLASS_RETURN(jc_Window, "java/awt/Window", NSWindowTabbingModeDisallowed);
DECLARE_METHOD_RETURN(jm_hasTabbingMode, jc_Window, "hasTabbingMode", "()Z", NSWindowTabbingModeDisallowed);
result = (*env)->CallBooleanMethod(env, awtWindow, jm_hasTabbingMode) == JNI_TRUE ? YES : NO;
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, awtWindow);
}
(*env)->DeleteLocalRef(env, platformWindow);
}
#ifdef DEBUG
NSLog(@"=== getJavaWindowTabbingMode: %d ===", result);
#endif
return result ? NSWindowTabbingModeAutomatic : NSWindowTabbingModeDisallowed;
}
+ (AWTWindow *) getTopmostWindowUnderMouse {
NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
NSWindow *window;
@@ -697,6 +796,12 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)windowDidResize:(NSNotification *)notification {
AWT_ASSERT_APPKIT_THREAD;
if (self.isEnterFullScreen && ignoreResizeWindowDuringAnotherWindowEnd) {
#ifdef DEBUG
NSLog(@"=== Native.windowDidResize: %@ | ignored in transition to fullscreen ===", self.nsWindow.title);
#endif
return;
}
[self _deliverMoveResizeEvent];
}
@@ -975,6 +1080,8 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
[self allowMovingChildrenBetweenSpaces:YES];
self.isEnterFullScreen = YES;
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CPLATFORM_WINDOW_CLASS();
DECLARE_METHOD(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
@@ -988,6 +1095,8 @@ AWT_ASSERT_APPKIT_THREAD;
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = YES;
[self allowMovingChildrenBetweenSpaces:NO];
JNIEnv *env = [ThreadUtilities getJNIEnv];
@@ -1004,6 +1113,8 @@ AWT_ASSERT_APPKIT_THREAD;
}
- (void)windowWillExitFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = NO;
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CPLATFORM_WINDOW_CLASS();
DECLARE_METHOD(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");
@@ -1022,6 +1133,8 @@ AWT_ASSERT_APPKIT_THREAD;
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = NO;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow);
if (platformWindow != NULL) {
@@ -1797,6 +1910,8 @@ JNI_COCOA_ENTER(env);
[nsWindow setDelegate: nil];
[window release];
ignoreResizeWindowDuringAnotherWindowEnd = NO;
}];
JNI_COCOA_EXIT(env);

View File

@@ -4032,6 +4032,39 @@ public class Window extends Container implements Accessible {
ignoreMouseEvents = ignore;
}
private volatile boolean hasTabbingMode;
boolean hasTabbingMode() {
return hasTabbingMode;
}
/**
* Set via reflection (JB JdkEx API).
*/
void setTabbingMode() {
hasTabbingMode = true;
}
private volatile Runnable moveTabToNewWindowCallback;
void runMoveTabToNewWindowCallback() {
if (moveTabToNewWindowCallback != null) {
Runnable callback = moveTabToNewWindowCallback;
SunToolkit.executeOnEventHandlerThread(this, new Runnable() {
public void run() {
callback.run();
}
});
}
}
/**
* Set via reflection (JB JdkEx API).
*/
void setMoveTabToNewWindowCallback(Runnable moveTabToNewWindowCallback) {
this.moveTabToNewWindowCallback = moveTabToNewWindowCallback;
}
// ************************** MIXING CODE *******************************
// A window has an owner, but it does NOT have a container