mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
macOS large title bar: fixed wrong "main" JToolBar height and left inset after leaving full screen
This commit is contained in:
@@ -54,7 +54,7 @@ public class FlatNativeMacLibrary
|
|||||||
|
|
||||||
public native static boolean setWindowRoundedBorder( Window window, float radius, float borderWidth, int borderColor );
|
public native static boolean setWindowRoundedBorder( Window window, float radius, float borderWidth, int borderColor );
|
||||||
|
|
||||||
public native static void setWindowToolbar( Window window, boolean hasToolbar );
|
public native static boolean setWindowToolbar( Window window, boolean hasToolbar );
|
||||||
public native static int getWindowButtonAreaWidth( Window window );
|
public native static int getWindowButtonAreaWidth( Window window );
|
||||||
public native static int getWindowTitleBarHeight( Window window );
|
public native static int getWindowTitleBarHeight( Window window );
|
||||||
public native static boolean isWindowFullScreen( Window window );
|
public native static boolean isWindowFullScreen( Window window );
|
||||||
|
|||||||
@@ -116,11 +116,7 @@ public class FlatToolBarBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
// on macOS, add some extra space to left side for close/minimize/zoom buttons (if necessary)
|
// on macOS, add some extra space to left side for close/minimize/zoom buttons (if necessary)
|
||||||
if( c instanceof JToolBar &&
|
if( c instanceof JToolBar && FlatToolBarUI.isMacOSMainToolbar( (JToolBar) c ) ) {
|
||||||
FlatToolBarUI.isMacOSMainToolbar( (JToolBar) c ) &&
|
|
||||||
(!FlatNativeMacLibrary.isLoaded() ||
|
|
||||||
!FlatNativeMacLibrary.isWindowFullScreen( SwingUtilities.windowForComponent( c ) )) )
|
|
||||||
{
|
|
||||||
// get button area width from macOS
|
// get button area width from macOS
|
||||||
int buttonBarWidth = FlatNativeMacLibrary.isLoaded()
|
int buttonBarWidth = FlatNativeMacLibrary.isLoaded()
|
||||||
? FlatNativeMacLibrary.getWindowButtonAreaWidth( SwingUtilities.windowForComponent( c ) )
|
? FlatNativeMacLibrary.getWindowButtonAreaWidth( SwingUtilities.windowForComponent( c ) )
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -18,9 +18,9 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setW
|
|||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
* Method: setWindowToolbar
|
* Method: setWindowToolbar
|
||||||
* Signature: (Ljava/awt/Window;Z)V
|
* Signature: (Ljava/awt/Window;Z)Z
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowToolbar
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowToolbar
|
||||||
(JNIEnv *, jclass, jobject, jboolean);
|
(JNIEnv *, jclass, jobject, jboolean);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -25,6 +25,27 @@
|
|||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@interface WindowData : NSObject
|
||||||
|
// used when window is full screen
|
||||||
|
@property (nonatomic) int lastWindowButtonAreaWidth;
|
||||||
|
@property (nonatomic) int lastWindowTitleBarHeight;
|
||||||
|
|
||||||
|
// full screen observers
|
||||||
|
@property (nonatomic) id willEnterFullScreenObserver;
|
||||||
|
@property (nonatomic) id didExitFullScreenObserver;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation WindowData
|
||||||
|
@end
|
||||||
|
|
||||||
|
// declare internal methods
|
||||||
|
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window );
|
||||||
|
WindowData* getWindowData( NSWindow* nsWindow, bool allocate );
|
||||||
|
int getWindowButtonAreaWidth( NSWindow* nsWindow );
|
||||||
|
int getWindowTitleBarHeight( NSWindow* nsWindow );
|
||||||
|
bool isWindowFullScreen( NSWindow* nsWindow );
|
||||||
|
|
||||||
|
|
||||||
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
||||||
if( window == NULL )
|
if( window == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -50,6 +71,16 @@ NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
|||||||
return (NSWindow *) jlong_to_ptr( env->GetLongField( platformWindow, ptrID ) );
|
return (NSWindow *) jlong_to_ptr( env->GetLongField( platformWindow, ptrID ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowData* getWindowData( NSWindow* nsWindow, bool allocate ) {
|
||||||
|
static char key;
|
||||||
|
WindowData* windowData = objc_getAssociatedObject( nsWindow, &key );
|
||||||
|
if( windowData == NULL && allocate ) {
|
||||||
|
windowData = [WindowData new];
|
||||||
|
objc_setAssociatedObject( nsWindow, &key, windowData, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
|
||||||
|
}
|
||||||
|
return windowData;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowRoundedBorder
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowRoundedBorder
|
||||||
( JNIEnv* env, jclass cls, jobject window, jfloat radius, jfloat borderWidth, jint borderColor )
|
( JNIEnv* env, jclass cls, jobject window, jfloat radius, jfloat borderWidth, jint borderColor )
|
||||||
@@ -90,20 +121,22 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setW
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowToolbar
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowToolbar
|
||||||
( JNIEnv* env, jclass cls, jobject window, jboolean hasToolbar )
|
( JNIEnv* env, jclass cls, jobject window, jboolean hasToolbar )
|
||||||
{
|
{
|
||||||
JNI_COCOA_ENTER()
|
JNI_COCOA_ENTER()
|
||||||
|
|
||||||
NSWindow* nsWindow = getNSWindow( env, cls, window );
|
NSWindow* nsWindow = getNSWindow( env, cls, window );
|
||||||
if( nsWindow == NULL )
|
if( nsWindow == NULL )
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
if( hasToolbar == (nsWindow.toolbar != NULL) )
|
if( hasToolbar == (nsWindow.toolbar != NULL) )
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
|
WindowData* windowData = getWindowData( nsWindow, true );
|
||||||
|
|
||||||
[FlatJNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
|
[FlatJNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
|
||||||
NSLog( @"\n%@\n\n", [nsWindow.contentView.superview _subtreeDescription] );
|
// NSLog( @"\n%@\n\n", [nsWindow.contentView.superview _subtreeDescription] );
|
||||||
|
|
||||||
// add/remove toolbar
|
// add/remove toolbar
|
||||||
NSToolbar* toolbar = NULL;
|
NSToolbar* toolbar = NULL;
|
||||||
@@ -113,45 +146,51 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindo
|
|||||||
}
|
}
|
||||||
nsWindow.toolbar = toolbar;
|
nsWindow.toolbar = toolbar;
|
||||||
|
|
||||||
NSLog( @"\n%@\n\n", [nsWindow.contentView.superview _subtreeDescription] );
|
// NSLog( @"\n%@\n\n", [nsWindow.contentView.superview _subtreeDescription] );
|
||||||
|
|
||||||
// when window becomes full screen, it is necessary to hide the toolbar
|
// when window becomes full screen, it is necessary to hide the toolbar
|
||||||
// because it otherwise is shown non-transparent and hides Swing components
|
// because it otherwise is shown non-transparent and hides Swing components
|
||||||
static char enterObserverKey;
|
|
||||||
static char exitObserverKey;
|
|
||||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||||
if( hasToolbar ) {
|
if( hasToolbar ) {
|
||||||
NSLog( @"add observers %@", nsWindow );
|
// NSLog( @"add observers %@", nsWindow );
|
||||||
id enterObserver = [center addObserverForName:NSWindowWillEnterFullScreenNotification
|
windowData.willEnterFullScreenObserver = [center addObserverForName:NSWindowWillEnterFullScreenNotification
|
||||||
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
||||||
NSLog( @"enter full screen %@", nsWindow );
|
// NSLog( @"enter full screen %@", nsWindow );
|
||||||
if( nsWindow.toolbar != NULL )
|
if( nsWindow.toolbar != NULL ) {
|
||||||
|
// remember button area width, which is used later when window exits full screen
|
||||||
|
// remembar title bar height so that "main" JToolBar keeps its height in full screen
|
||||||
|
windowData.lastWindowButtonAreaWidth = getWindowButtonAreaWidth( nsWindow );
|
||||||
|
windowData.lastWindowTitleBarHeight = getWindowTitleBarHeight( nsWindow );
|
||||||
|
|
||||||
nsWindow.toolbar.visible = NO;
|
nsWindow.toolbar.visible = NO;
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
id exitObserver = [center addObserverForName:NSWindowDidExitFullScreenNotification
|
windowData.didExitFullScreenObserver = [center addObserverForName:NSWindowDidExitFullScreenNotification
|
||||||
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
||||||
NSLog( @"exit full screen %@", nsWindow );
|
// NSLog( @"exit full screen %@", nsWindow );
|
||||||
if( nsWindow.toolbar != NULL )
|
if( nsWindow.toolbar != NULL )
|
||||||
nsWindow.toolbar.visible = YES;
|
nsWindow.toolbar.visible = YES;
|
||||||
|
|
||||||
|
windowData.lastWindowButtonAreaWidth = 0;
|
||||||
|
windowData.lastWindowTitleBarHeight = 0;
|
||||||
}];
|
}];
|
||||||
objc_setAssociatedObject( nsWindow, &enterObserverKey, enterObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
|
|
||||||
objc_setAssociatedObject( nsWindow, &exitObserverKey, exitObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
|
|
||||||
} else {
|
} else {
|
||||||
NSLog( @"remove observers %@", nsWindow );
|
// NSLog( @"remove observers %@", nsWindow );
|
||||||
id enterObserver = objc_getAssociatedObject( nsWindow, &enterObserverKey );
|
if( windowData.willEnterFullScreenObserver != NULL ) {
|
||||||
id exitObserver = objc_getAssociatedObject( nsWindow, &exitObserverKey );
|
[center removeObserver:windowData.willEnterFullScreenObserver];
|
||||||
if( enterObserver != NULL ) {
|
windowData.willEnterFullScreenObserver = nil;
|
||||||
[center removeObserver:enterObserver];
|
|
||||||
objc_setAssociatedObject( nsWindow, &enterObserverKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
|
|
||||||
}
|
}
|
||||||
if( exitObserver != NULL ) {
|
if( windowData.didExitFullScreenObserver != NULL ) {
|
||||||
[center removeObserver:exitObserver];
|
[center removeObserver:windowData.didExitFullScreenObserver];
|
||||||
objc_setAssociatedObject( nsWindow, &exitObserverKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
|
windowData.didExitFullScreenObserver = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
JNI_COCOA_EXIT()
|
JNI_COCOA_EXIT()
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@@ -164,6 +203,23 @@ JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_getWindo
|
|||||||
if( nsWindow == NULL )
|
if( nsWindow == NULL )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// return zero if window is full screen because close/minimize/zoom buttons are hidden
|
||||||
|
if( isWindowFullScreen( nsWindow ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// use remembered value if window is in transition from full screen to non-full screen
|
||||||
|
// because NSToolbar is not yet visible
|
||||||
|
WindowData* windowData = getWindowData( nsWindow, false );
|
||||||
|
if( windowData != NULL && windowData.lastWindowButtonAreaWidth > 0 )
|
||||||
|
return windowData.lastWindowButtonAreaWidth;
|
||||||
|
|
||||||
|
return getWindowButtonAreaWidth( nsWindow );
|
||||||
|
|
||||||
|
JNI_COCOA_EXIT()
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWindowButtonAreaWidth( NSWindow* nsWindow ) {
|
||||||
// get buttons
|
// get buttons
|
||||||
NSView* buttons[3] = {
|
NSView* buttons[3] = {
|
||||||
[nsWindow standardWindowButton:NSWindowCloseButton],
|
[nsWindow standardWindowButton:NSWindowCloseButton],
|
||||||
@@ -193,8 +249,6 @@ JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_getWindo
|
|||||||
// 'right' is the actual button area width (from left window edge)
|
// 'right' is the actual button area width (from left window edge)
|
||||||
// adding 'left' to add same empty space on right side as on left side
|
// adding 'left' to add same empty space on right side as on left side
|
||||||
return right + left;
|
return right + left;
|
||||||
|
|
||||||
JNI_COCOA_EXIT()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@@ -207,14 +261,24 @@ JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_getWindo
|
|||||||
if( nsWindow == NULL )
|
if( nsWindow == NULL )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
// use remembered value if window is full screen because NSToolbar is hidden
|
||||||
|
WindowData* windowData = getWindowData( nsWindow, false );
|
||||||
|
if( windowData != NULL && windowData.lastWindowTitleBarHeight > 0 )
|
||||||
|
return windowData.lastWindowTitleBarHeight;
|
||||||
|
|
||||||
|
return getWindowTitleBarHeight( nsWindow );
|
||||||
|
|
||||||
|
JNI_COCOA_EXIT()
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWindowTitleBarHeight( NSWindow* nsWindow ) {
|
||||||
NSView* closeButton = [nsWindow standardWindowButton:NSWindowCloseButton];
|
NSView* closeButton = [nsWindow standardWindowButton:NSWindowCloseButton];
|
||||||
if( closeButton == NULL )
|
if( closeButton == NULL )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
NSView* titlebar = closeButton.superview;
|
NSView* titlebar = closeButton.superview;
|
||||||
return titlebar.bounds.size.height;
|
return titlebar.bounds.size.height;
|
||||||
|
|
||||||
JNI_COCOA_EXIT()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@@ -227,8 +291,12 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_isWi
|
|||||||
if( nsWindow == NULL )
|
if( nsWindow == NULL )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return (jboolean) (([nsWindow styleMask] & NSWindowStyleMaskFullScreen) != 0);
|
return (jboolean) isWindowFullScreen( nsWindow );
|
||||||
|
|
||||||
JNI_COCOA_EXIT()
|
JNI_COCOA_EXIT()
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isWindowFullScreen( NSWindow* nsWindow ) {
|
||||||
|
return ((nsWindow.styleMask & NSWindowStyleMaskFullScreen) != 0);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user