mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
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 commitf02e31a440) (cherry-picked from commita84736ebcc)
This commit is contained in:
committed by
Alexey Ushakov
parent
67ab7032c8
commit
0cf6d2da8d
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user