Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native/sun/awt/AWTWindow.m
38829 views
/*1* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#ifdef MACOSX_NOTIOS // prevent merge conflicts26#import <Cocoa/Cocoa.h>27#import <JavaNativeFoundation/JavaNativeFoundation.h>28#import <JavaRuntimeSupport/JavaRuntimeSupport.h>2930#import "sun_lwawt_macosx_CPlatformWindow.h"31#import "com_apple_eawt_event_GestureHandler.h"32#import "com_apple_eawt_FullScreenHandler.h"33#import "ApplicationDelegate.h"3435#import "AWTWindow.h"36#import "AWTView.h"37#import "CMenu.h"38#import "CMenuBar.h"39#import "LWCToolkit.h"40#import "GeomUtilities.h"41#import "ThreadUtilities.h"42#import "OSVersion.h"4344#define MASK(KEY) \45(sun_lwawt_macosx_CPlatformWindow_ ## KEY)4647#define IS(BITS, KEY) \48((BITS & MASK(KEY)) != 0)4950#define SET(BITS, KEY, VALUE) \51BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)5253static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");5455// Cocoa windowDidBecomeKey/windowDidResignKey notifications56// doesn't provide information about "opposite" window, so we57// have to do a bit of tracking. This variable points to a window58// which had been the key window just before a new key window59// was set. It would be nil if the new key window isn't an AWT60// window or the app currently has no key window.61static AWTWindow* lastKeyWindow = nil;6263// --------------------------------------------------------------64// NSWindow/NSPanel descendants implementation65#define AWT_NS_WINDOW_IMPLEMENTATION \66- (id) initWithDelegate:(AWTWindow *)delegate \67frameRect:(NSRect)contectRect \68styleMask:(NSUInteger)styleMask \69contentView:(NSView *)view \70{ \71self = [super initWithContentRect:contectRect \72styleMask:styleMask \73backing:NSBackingStoreBuffered \74defer:NO]; \75\76if (self == nil) return nil; \77\78[self setDelegate:delegate]; \79[self setContentView:view]; \80[self setInitialFirstResponder:view]; \81[self setReleasedWhenClosed:NO]; \82[self setPreservesContentDuringLiveResize:YES]; \83\84return self; \85} \86\87/* NSWindow overrides */ \88- (BOOL) canBecomeKeyWindow { \89return [(AWTWindow*)[self delegate] canBecomeKeyWindow]; \90} \91\92- (BOOL) canBecomeMainWindow { \93return [(AWTWindow*)[self delegate] canBecomeMainWindow]; \94} \95\96- (BOOL) worksWhenModal { \97return [(AWTWindow*)[self delegate] worksWhenModal]; \98} \99\100- (void)sendEvent:(NSEvent *)event { \101[(AWTWindow*)[self delegate] sendEvent:event]; \102[super sendEvent:event]; \103}104105@implementation AWTWindow_Normal106AWT_NS_WINDOW_IMPLEMENTATION107108// Gesture support109- (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {110AWT_ASSERT_APPKIT_THREAD;111112JNIEnv *env = [ThreadUtilities getJNIEnv];113jobject platformWindow = [((AWTWindow *)self.delegate).javaPlatformWindow jObjectWithEnv:env];114if (platformWindow != NULL) {115// extract the target AWT Window object out of the CPlatformWindow116static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");117jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);118if (awtWindow != NULL) {119// translate the point into Java coordinates120NSPoint loc = [event locationInWindow];121loc.y = [self frame].size.height - loc.y;122123// send up to the GestureHandler to recursively dispatch on the AWT event thread124static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");125static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");126JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);127(*env)->DeleteLocalRef(env, awtWindow);128}129(*env)->DeleteLocalRef(env, platformWindow);130}131}132133- (void)beginGestureWithEvent:(NSEvent *)event {134[self postGesture:event135as:com_apple_eawt_event_GestureHandler_PHASE136a:-1.0137b:0.0];138}139140- (void)endGestureWithEvent:(NSEvent *)event {141[self postGesture:event142as:com_apple_eawt_event_GestureHandler_PHASE143a:1.0144b:0.0];145}146147- (void)magnifyWithEvent:(NSEvent *)event {148[self postGesture:event149as:com_apple_eawt_event_GestureHandler_MAGNIFY150a:[event magnification]151b:0.0];152}153154- (void)rotateWithEvent:(NSEvent *)event {155[self postGesture:event156as:com_apple_eawt_event_GestureHandler_ROTATE157a:[event rotation]158b:0.0];159}160161- (void)swipeWithEvent:(NSEvent *)event {162[self postGesture:event163as:com_apple_eawt_event_GestureHandler_SWIPE164a:[event deltaX]165b:[event deltaY]];166}167168@end169@implementation AWTWindow_Panel170AWT_NS_WINDOW_IMPLEMENTATION171@end172// END of NSWindow/NSPanel descendants implementation173// --------------------------------------------------------------174175176@implementation AWTWindow177178@synthesize nsWindow;179@synthesize javaPlatformWindow;180@synthesize javaMenuBar;181@synthesize javaMinSize;182@synthesize javaMaxSize;183@synthesize styleBits;184@synthesize isEnabled;185@synthesize ownerWindow;186@synthesize preFullScreenLevel;187@synthesize isMinimizing;188189- (void) updateMinMaxSize:(BOOL)resizable {190if (resizable) {191[self.nsWindow setMinSize:self.javaMinSize];192[self.nsWindow setMaxSize:self.javaMaxSize];193} else {194NSRect currentFrame = [self.nsWindow frame];195[self.nsWindow setMinSize:currentFrame.size];196[self.nsWindow setMaxSize:currentFrame.size];197}198}199200// creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits201+ (NSUInteger) styleMaskForStyleBits:(jint)styleBits {202NSUInteger type = 0;203if (IS(styleBits, DECORATED)) {204type |= NSTitledWindowMask;205if (IS(styleBits, CLOSEABLE)) type |= NSClosableWindowMask;206if (IS(styleBits, MINIMIZABLE)) type |= NSMiniaturizableWindowMask;207if (IS(styleBits, RESIZABLE)) type |= NSResizableWindowMask;208if (IS(styleBits, FULL_WINDOW_CONTENT)) type |= NSFullSizeContentViewWindowMask;209} else {210type |= NSBorderlessWindowMask;211}212213if (IS(styleBits, TEXTURED)) type |= NSTexturedBackgroundWindowMask;214if (IS(styleBits, UNIFIED)) type |= NSUnifiedTitleAndToolbarWindowMask;215if (IS(styleBits, UTILITY)) type |= NSUtilityWindowMask;216if (IS(styleBits, HUD)) type |= NSHUDWindowMask;217if (IS(styleBits, SHEET)) type |= NSDocModalWindowMask;218if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;219220return type;221}222223// updates _METHOD_PROP_BITMASK based properties on the window224- (void) setPropertiesForStyleBits:(jint)bits mask:(jint)mask {225if (IS(mask, RESIZABLE)) {226BOOL resizable = IS(bits, RESIZABLE);227[self updateMinMaxSize:resizable];228[self.nsWindow setShowsResizeIndicator:resizable];229// Zoom button should be disabled, if the window is not resizable,230// otherwise button should be restored to initial state.231BOOL zoom = resizable && IS(bits, ZOOMABLE);232[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:zoom];233}234235if (IS(mask, HAS_SHADOW)) {236[self.nsWindow setHasShadow:IS(bits, HAS_SHADOW)];237}238239if (IS(mask, ZOOMABLE)) {240[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:IS(bits, ZOOMABLE)];241}242243if (IS(mask, ALWAYS_ON_TOP)) {244[self.nsWindow setLevel:IS(bits, ALWAYS_ON_TOP) ? NSFloatingWindowLevel : NSNormalWindowLevel];245}246247if (IS(mask, HIDES_ON_DEACTIVATE)) {248[self.nsWindow setHidesOnDeactivate:IS(bits, HIDES_ON_DEACTIVATE)];249}250251if (IS(mask, DRAGGABLE_BACKGROUND)) {252[self.nsWindow setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];253}254255if (IS(mask, DOCUMENT_MODIFIED)) {256[self.nsWindow setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];257}258259if (IS(mask, FULLSCREENABLE) && [self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {260if (IS(bits, FULLSCREENABLE)) {261[self.nsWindow setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];262} else {263[self.nsWindow setCollectionBehavior:NSWindowCollectionBehaviorDefault];264}265}266267if (IS(mask, TRANSPARENT_TITLE_BAR) && [self.nsWindow respondsToSelector:@selector(setTitlebarAppearsTransparent:)]) {268[self.nsWindow setTitlebarAppearsTransparent:IS(bits, TRANSPARENT_TITLE_BAR)];269}270}271272- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow273ownerWindow:owner274styleBits:(jint)bits275frameRect:(NSRect)rect276contentView:(NSView *)view277{278AWT_ASSERT_APPKIT_THREAD;279280NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];281NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];282if (contentRect.size.width <= 0.0) {283contentRect.size.width = 1.0;284}285if (contentRect.size.height <= 0.0) {286contentRect.size.height = 1.0;287}288289self = [super init];290291if (self == nil) return nil; // no hope292293if (IS(bits, UTILITY) ||294IS(bits, NONACTIVATING) ||295IS(bits, HUD) ||296IS(bits, HIDES_ON_DEACTIVATE))297{298self.nsWindow = [[AWTWindow_Panel alloc] initWithDelegate:self299frameRect:contentRect300styleMask:styleMask301contentView:view];302}303else304{305// These windows will appear in the window list in the dock icon menu306self.nsWindow = [[AWTWindow_Normal alloc] initWithDelegate:self307frameRect:contentRect308styleMask:styleMask309contentView:view];310}311312if (self.nsWindow == nil) return nil; // no hope either313[self.nsWindow release]; // the property retains the object already314315self.isEnabled = YES;316self.isMinimizing = NO;317self.javaPlatformWindow = platformWindow;318self.styleBits = bits;319self.ownerWindow = owner;320[self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];321322if (IS(self.styleBits, IS_POPUP)) {323[self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];324}325326return self;327}328329+ (BOOL) isAWTWindow:(NSWindow *)window {330return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];331}332333// Retrieves the list of possible window layers (levels)334+ (NSArray*) getWindowLayers {335static NSArray *windowLayers;336static dispatch_once_t token;337338// Initialize the list of possible window layers339dispatch_once(&token, ^{340// The layers are ordered from front to back, (i.e. the toppest one is the first)341windowLayers = [NSArray arrayWithObjects:342[NSNumber numberWithInt:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)],343[NSNumber numberWithInt:CGWindowLevelForKey(kCGFloatingWindowLevelKey)],344[NSNumber numberWithInt:CGWindowLevelForKey(kCGNormalWindowLevelKey)],345nil346];347[windowLayers retain];348});349return windowLayers;350}351352// returns id for the topmost window under mouse353+ (NSInteger) getTopmostWindowUnderMouseID {354NSInteger result = -1;355356NSArray *windowLayers = [AWTWindow getWindowLayers];357// Looking for the window under mouse starting from the toppest layer358for (NSNumber *layer in windowLayers) {359result = [AWTWindow getTopmostWindowUnderMouseIDImpl:[layer integerValue]];360if (result != -1) {361break;362}363}364return result;365}366367+ (NSInteger) getTopmostWindowUnderMouseIDImpl:(NSInteger)windowLayer {368NSInteger result = -1;369370NSRect screenRect = [[NSScreen mainScreen] frame];371NSPoint nsMouseLocation = [NSEvent mouseLocation];372CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);373374NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);375376for (NSDictionary *window in windows) {377NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];378if (layer == windowLayer) {379CGRect rect;380CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);381if (CGRectContainsPoint(rect, cgMouseLocation)) {382result = [[window objectForKey:(id)kCGWindowNumber] integerValue];383break;384}385}386}387[windows release];388return result;389}390391// checks that this window is under the mouse cursor and this point is not overlapped by others windows392- (BOOL) isTopmostWindowUnderMouse {393return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];394}395396+ (AWTWindow *) getTopmostWindowUnderMouse {397NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];398NSWindow *window;399400NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];401402while ((window = [windowEnumerator nextObject]) != nil) {403if ([window windowNumber] == topmostWindowUnderMouseID) {404BOOL isAWTWindow = [AWTWindow isAWTWindow: window];405return isAWTWindow ? (AWTWindow *) [window delegate] : nil;406}407}408return nil;409}410411+ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {412413NSPoint screenLocation = [NSEvent mouseLocation];414NSPoint windowLocation = [window convertScreenToBase: screenLocation];415int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;416417NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType418location: windowLocation419modifierFlags: modifierFlags420timestamp: 0421windowNumber: [window windowNumber]422context: nil423eventNumber: 0424trackingNumber: 0425userData: nil426];427428[[window contentView] deliverJavaMouseEvent: mouseEvent];429}430431+ (void) synthesizeMouseEnteredExitedEventsForAllWindows {432433NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];434NSArray *windows = [NSApp windows];435NSWindow *window;436437NSEnumerator *windowEnumerator = [windows objectEnumerator];438while ((window = [windowEnumerator nextObject]) != nil) {439if ([AWTWindow isAWTWindow: window]) {440BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);441BOOL mouseIsOver = [[window contentView] mouseIsOver];442if (isUnderMouse && !mouseIsOver) {443[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];444} else if (!isUnderMouse && mouseIsOver) {445[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];446}447}448}449}450451+ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {452AWT_ASSERT_APPKIT_THREAD;453NSScreen *screen = [window screen];454NSDictionary *deviceDescription = [screen deviceDescription];455return [deviceDescription objectForKey:@"NSScreenNumber"];456}457458- (void) dealloc {459AWT_ASSERT_APPKIT_THREAD;460461JNIEnv *env = [ThreadUtilities getJNIEnvUncached];462[self.javaPlatformWindow setJObject:nil withEnv:env];463self.javaPlatformWindow = nil;464self.nsWindow = nil;465self.ownerWindow = nil;466[super dealloc];467}468469// Tests whether window is blocked by modal dialog/window470- (BOOL) isBlocked {471BOOL isBlocked = NO;472473JNIEnv *env = [ThreadUtilities getJNIEnv];474jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];475if (platformWindow != NULL) {476static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isBlocked", "()Z");477isBlocked = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;478(*env)->DeleteLocalRef(env, platformWindow);479}480481return isBlocked;482}483484- (BOOL) isSimpleWindowOwnedByEmbeddedFrame {485BOOL isSimpleWindowOwnedByEmbeddedFrame = NO;486487JNIEnv *env = [ThreadUtilities getJNIEnv];488jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];489if (platformWindow != NULL) {490static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isSimpleWindowOwnedByEmbeddedFrame", "()Z");491isSimpleWindowOwnedByEmbeddedFrame = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;492(*env)->DeleteLocalRef(env, platformWindow);493}494495return isSimpleWindowOwnedByEmbeddedFrame;496}497498// Tests whether the corresponding Java platform window is visible or not499+ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {500BOOL isVisible = NO;501502if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {503AWTWindow *awtWindow = (AWTWindow *)[window delegate];504[AWTToolkit eventCountPlusPlus];505506JNIEnv *env = [ThreadUtilities getJNIEnv];507jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];508if (platformWindow != NULL) {509static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");510isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;511(*env)->DeleteLocalRef(env, platformWindow);512513}514}515return isVisible;516}517518// Orders window's childs based on the current focus state519- (void) orderChildWindows:(BOOL)focus {520AWT_ASSERT_APPKIT_THREAD;521522if (self.isMinimizing || [self isBlocked]) {523// Do not perform any ordering, if iconify is in progress524// or the window is blocked by a modal window525return;526}527528NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];529NSWindow *window;530while ((window = [windowEnumerator nextObject]) != nil) {531if ([AWTWindow isJavaPlatformWindowVisible:window]) {532AWTWindow *awtWindow = (AWTWindow *)[window delegate];533AWTWindow *owner = awtWindow.ownerWindow;534if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {535// Do not order 'always on top' windows536continue;537}538while (awtWindow.ownerWindow != nil) {539if (awtWindow.ownerWindow == self) {540if (focus) {541// Move the childWindow to floating level542// so it will appear in front of its543// parent which owns the focus544[window setLevel:NSFloatingWindowLevel];545} else {546// Focus owner has changed, move the childWindow547// back to normal window level548[window setLevel:NSNormalWindowLevel];549}550// The childWindow should be displayed in front of551// its nearest parentWindow552[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];553break;554}555awtWindow = awtWindow.ownerWindow;556}557}558}559}560561// NSWindow overrides562- (BOOL) canBecomeKeyWindow {563AWT_ASSERT_APPKIT_THREAD;564return self.isEnabled && (IS(self.styleBits, SHOULD_BECOME_KEY) || [self isSimpleWindowOwnedByEmbeddedFrame]);565}566567- (BOOL) canBecomeMainWindow {568AWT_ASSERT_APPKIT_THREAD;569if (!self.isEnabled) {570// Native system can bring up the NSWindow to571// the top even if the window is not main.572// We should bring up the modal dialog manually573[AWTToolkit eventCountPlusPlus];574575JNIEnv *env = [ThreadUtilities getJNIEnv];576jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];577if (platformWindow != NULL) {578static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,579"checkBlockingAndOrder", "()Z");580JNFCallBooleanMethod(env, platformWindow, jm_checkBlockingAndOrder);581(*env)->DeleteLocalRef(env, platformWindow);582}583}584585return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);586}587588- (BOOL) worksWhenModal {589AWT_ASSERT_APPKIT_THREAD;590return IS(self.styleBits, MODAL_EXCLUDED);591}592593594// NSWindowDelegate methods595596- (void) _deliverMoveResizeEvent {597AWT_ASSERT_APPKIT_THREAD;598599// deliver the event if this is a user-initiated live resize or as a side-effect600// of a Java initiated resize, because AppKit can override the bounds and force601// the bounds of the window to avoid the Dock or remain on screen.602[AWTToolkit eventCountPlusPlus];603JNIEnv *env = [ThreadUtilities getJNIEnv];604jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];605if (platformWindow == NULL) {606// TODO: create generic AWT assert607}608609NSRect frame = ConvertNSScreenRect(env, [self.nsWindow frame]);610611static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIIIZ)V");612JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,613(jint)frame.origin.x,614(jint)frame.origin.y,615(jint)frame.size.width,616(jint)frame.size.height,617(jboolean)[self.nsWindow inLiveResize]);618(*env)->DeleteLocalRef(env, platformWindow);619620[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];621}622623- (void)windowDidMove:(NSNotification *)notification {624AWT_ASSERT_APPKIT_THREAD;625626[self _deliverMoveResizeEvent];627}628629- (void)windowDidResize:(NSNotification *)notification {630AWT_ASSERT_APPKIT_THREAD;631632[self _deliverMoveResizeEvent];633}634635- (void)windowDidExpose:(NSNotification *)notification {636AWT_ASSERT_APPKIT_THREAD;637638[AWTToolkit eventCountPlusPlus];639// TODO: don't see this callback invoked anytime so we track640// window exposing in _setVisible:(BOOL)641}642643// Hides/shows window's childs during iconify/de-iconify operation644- (void) iconifyChildWindows:(BOOL)iconify {645AWT_ASSERT_APPKIT_THREAD;646647NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];648NSWindow *window;649while ((window = [windowEnumerator nextObject]) != nil) {650if ([AWTWindow isJavaPlatformWindowVisible:window]) {651AWTWindow *awtWindow = (AWTWindow *)[window delegate];652while (awtWindow.ownerWindow != nil) {653if (awtWindow.ownerWindow == self) {654if (iconify) {655[window orderOut:window];656} else {657[window orderFront:window];658}659break;660}661awtWindow = awtWindow.ownerWindow;662}663}664}665}666667- (void) _deliverIconify:(BOOL)iconify {668AWT_ASSERT_APPKIT_THREAD;669670[AWTToolkit eventCountPlusPlus];671JNIEnv *env = [ThreadUtilities getJNIEnv];672jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];673if (platformWindow != NULL) {674static JNF_MEMBER_CACHE(jm_deliverIconify, jc_CPlatformWindow, "deliverIconify", "(Z)V");675JNFCallVoidMethod(env, platformWindow, jm_deliverIconify, iconify);676(*env)->DeleteLocalRef(env, platformWindow);677}678}679680- (void)windowWillMiniaturize:(NSNotification *)notification {681AWT_ASSERT_APPKIT_THREAD;682683self.isMinimizing = YES;684685JNIEnv *env = [ThreadUtilities getJNIEnv];686jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];687if (platformWindow != NULL) {688static JNF_MEMBER_CACHE(jm_windowWillMiniaturize, jc_CPlatformWindow, "windowWillMiniaturize", "()V");689JNFCallVoidMethod(env, platformWindow, jm_windowWillMiniaturize);690(*env)->DeleteLocalRef(env, platformWindow);691}692// Excplicitly make myself a key window to avoid possible693// negative visual effects during iconify operation694[self.nsWindow makeKeyAndOrderFront:self.nsWindow];695[self iconifyChildWindows:YES];696}697698- (void)windowDidMiniaturize:(NSNotification *)notification {699AWT_ASSERT_APPKIT_THREAD;700701[self _deliverIconify:JNI_TRUE];702self.isMinimizing = NO;703}704705- (void)windowDidDeminiaturize:(NSNotification *)notification {706AWT_ASSERT_APPKIT_THREAD;707708[self _deliverIconify:JNI_FALSE];709[self iconifyChildWindows:NO];710}711712- (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {713//AWT_ASSERT_APPKIT_THREAD;714JNIEnv *env = [ThreadUtilities getJNIEnvUncached];715jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];716if (platformWindow != NULL) {717jobject oppositeWindow = [opposite.javaPlatformWindow jObjectWithEnv:env];718719static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(ZLsun/lwawt/macosx/CPlatformWindow;)V");720JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused, oppositeWindow);721(*env)->DeleteLocalRef(env, platformWindow);722(*env)->DeleteLocalRef(env, oppositeWindow);723}724}725726727- (void) windowDidBecomeKey: (NSNotification *) notification {728AWT_ASSERT_APPKIT_THREAD;729[AWTToolkit eventCountPlusPlus];730AWTWindow *opposite = [AWTWindow lastKeyWindow];731732// Finds appropriate menubar in our hierarchy,733AWTWindow *awtWindow = self;734while (awtWindow.ownerWindow != nil) {735awtWindow = awtWindow.ownerWindow;736}737738CMenuBar *menuBar = nil;739BOOL isDisabled = NO;740if ([awtWindow.nsWindow isVisible]){741menuBar = awtWindow.javaMenuBar;742isDisabled = !awtWindow.isEnabled;743}744745if (menuBar == nil) {746menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];747isDisabled = NO;748}749750[CMenuBar activate:menuBar modallyDisabled:isDisabled];751752[AWTWindow setLastKeyWindow:nil];753754[self _deliverWindowFocusEvent:YES oppositeWindow: opposite];755[self orderChildWindows:YES];756}757758- (void) windowDidResignKey: (NSNotification *) notification {759// TODO: check why sometimes at start is invoked *not* on AppKit main thread.760AWT_ASSERT_APPKIT_THREAD;761[AWTToolkit eventCountPlusPlus];762[self.javaMenuBar deactivate];763764// In theory, this might cause flickering if the window gaining focus765// has its own menu. However, I couldn't reproduce it on practice, so766// perhaps this is a non issue.767CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar];768if (defaultMenu != nil) {769[CMenuBar activate:defaultMenu modallyDisabled:NO];770}771772// the new key window773NSWindow *keyWindow = [NSApp keyWindow];774AWTWindow *opposite = nil;775if ([AWTWindow isAWTWindow: keyWindow]) {776opposite = (AWTWindow *)[keyWindow delegate];777[AWTWindow setLastKeyWindow: self];778} else {779[AWTWindow setLastKeyWindow: nil];780}781782[self _deliverWindowFocusEvent:NO oppositeWindow: opposite];783[self orderChildWindows:NO];784}785786- (void) windowDidBecomeMain: (NSNotification *) notification {787AWT_ASSERT_APPKIT_THREAD;788[AWTToolkit eventCountPlusPlus];789790JNIEnv *env = [ThreadUtilities getJNIEnv];791jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];792if (platformWindow != NULL) {793static JNF_MEMBER_CACHE(jm_windowDidBecomeMain, jc_CPlatformWindow, "windowDidBecomeMain", "()V");794JNFCallVoidMethod(env, platformWindow, jm_windowDidBecomeMain);795(*env)->DeleteLocalRef(env, platformWindow);796}797}798799- (BOOL)windowShouldClose:(id)sender {800AWT_ASSERT_APPKIT_THREAD;801[AWTToolkit eventCountPlusPlus];802JNIEnv *env = [ThreadUtilities getJNIEnv];803jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];804if (platformWindow != NULL) {805static JNF_MEMBER_CACHE(jm_deliverWindowClosingEvent, jc_CPlatformWindow, "deliverWindowClosingEvent", "()V");806JNFCallVoidMethod(env, platformWindow, jm_deliverWindowClosingEvent);807(*env)->DeleteLocalRef(env, platformWindow);808}809// The window will be closed (if allowed) as result of sending Java event810return NO;811}812813814- (void)_notifyFullScreenOp:(jint)op withEnv:(JNIEnv *)env {815static JNF_CLASS_CACHE(jc_FullScreenHandler, "com/apple/eawt/FullScreenHandler");816static JNF_STATIC_MEMBER_CACHE(jm_notifyFullScreenOperation, jc_FullScreenHandler, "handleFullScreenEventFromNative", "(Ljava/awt/Window;I)V");817static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");818jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];819if (platformWindow != NULL) {820jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);821if (awtWindow != NULL) {822JNFCallStaticVoidMethod(env, jm_notifyFullScreenOperation, awtWindow, op);823(*env)->DeleteLocalRef(env, awtWindow);824}825(*env)->DeleteLocalRef(env, platformWindow);826}827}828829830- (void)windowWillEnterFullScreen:(NSNotification *)notification {831static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");832JNIEnv *env = [ThreadUtilities getJNIEnv];833jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];834if (platformWindow != NULL) {835JNFCallVoidMethod(env, platformWindow, jm_windowWillEnterFullScreen);836[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_ENTER withEnv:env];837(*env)->DeleteLocalRef(env, platformWindow);838}839}840841- (void)windowDidEnterFullScreen:(NSNotification *)notification {842static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");843JNIEnv *env = [ThreadUtilities getJNIEnv];844jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];845if (platformWindow != NULL) {846JNFCallVoidMethod(env, platformWindow, jm_windowDidEnterFullScreen);847[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_ENTER withEnv:env];848(*env)->DeleteLocalRef(env, platformWindow);849}850[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];851}852853- (void)windowWillExitFullScreen:(NSNotification *)notification {854static JNF_MEMBER_CACHE(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");855JNIEnv *env = [ThreadUtilities getJNIEnv];856jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];857if (platformWindow != NULL) {858JNFCallVoidMethod(env, platformWindow, jm_windowWillExitFullScreen);859[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_EXIT withEnv:env];860(*env)->DeleteLocalRef(env, platformWindow);861}862}863864- (void)windowDidExitFullScreen:(NSNotification *)notification {865static JNF_MEMBER_CACHE(jm_windowDidExitFullScreen, jc_CPlatformWindow, "windowDidExitFullScreen", "()V");866JNIEnv *env = [ThreadUtilities getJNIEnv];867jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];868if (platformWindow != NULL) {869JNFCallVoidMethod(env, platformWindow, jm_windowDidExitFullScreen);870[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_EXIT withEnv:env];871(*env)->DeleteLocalRef(env, platformWindow);872}873[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];874}875876- (void)sendEvent:(NSEvent *)event {877if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {878if ([self isBlocked]) {879// Move parent windows to front and make sure that a child window is displayed880// in front of its nearest parent.881if (self.ownerWindow != nil) {882JNIEnv *env = [ThreadUtilities getJNIEnvUncached];883jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];884if (platformWindow != NULL) {885static JNF_MEMBER_CACHE(jm_orderAboveSiblings, jc_CPlatformWindow, "orderAboveSiblings", "()V");886JNFCallVoidMethod(env,platformWindow, jm_orderAboveSiblings);887(*env)->DeleteLocalRef(env, platformWindow);888}889}890[self orderChildWindows:YES];891}892893NSPoint p = [NSEvent mouseLocation];894NSRect frame = [self.nsWindow frame];895NSRect contentRect = [self.nsWindow contentRectForFrameRect:frame];896897// Check if the click happened in the non-client area (title bar)898if (p.y >= (frame.origin.y + contentRect.size.height)) {899JNIEnv *env = [ThreadUtilities getJNIEnvUncached];900jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];901if (platformWindow != NULL) {902// Currently, no need to deliver the whole NSEvent.903static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");904JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);905(*env)->DeleteLocalRef(env, platformWindow);906}907}908}909}910911- (void)constrainSize:(NSSize*)size {912float minWidth = 0.f, minHeight = 0.f;913914if (IS(self.styleBits, DECORATED)) {915NSRect frame = [self.nsWindow frame];916NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self.nsWindow styleMask]];917918float top = frame.size.height - contentRect.size.height;919float left = contentRect.origin.x - frame.origin.x;920float bottom = contentRect.origin.y - frame.origin.y;921float right = frame.size.width - (contentRect.size.width + left);922923// Speculative estimation: 80 - enough for window decorations controls924minWidth += left + right + 80;925minHeight += top + bottom;926}927928minWidth = MAX(1.f, minWidth);929minHeight = MAX(1.f, minHeight);930931size->width = MAX(size->width, minWidth);932size->height = MAX(size->height, minHeight);933}934935- (void) setEnabled: (BOOL)flag {936self.isEnabled = flag;937938if (IS(self.styleBits, CLOSEABLE)) {939[[self.nsWindow standardWindowButton:NSWindowCloseButton] setEnabled: flag];940}941942if (IS(self.styleBits, MINIMIZABLE)) {943[[self.nsWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled: flag];944}945946if (IS(self.styleBits, ZOOMABLE)) {947[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled: flag];948}949950if (IS(self.styleBits, RESIZABLE)) {951[self updateMinMaxSize:flag];952[self.nsWindow setShowsResizeIndicator:flag];953}954}955956+ (void) setLastKeyWindow:(AWTWindow *)window {957[window retain];958[lastKeyWindow release];959lastKeyWindow = window;960}961962+ (AWTWindow *) lastKeyWindow {963return lastKeyWindow;964}965966- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame {967return !NSEqualSizes(self.nsWindow.frame.size, newFrame.size);968}969970971@end // AWTWindow972973974/*975* Class: sun_lwawt_macosx_CPlatformWindow976* Method: nativeCreateNSWindow977* Signature: (JJIIII)J978*/979JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow980(JNIEnv *env, jobject obj, jlong contentViewPtr, jlong ownerPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)981{982__block AWTWindow *window = nil;983984JNF_COCOA_ENTER(env);985986JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];987NSView *contentView = OBJC(contentViewPtr);988NSRect frameRect = NSMakeRect(x, y, w, h);989AWTWindow *owner = [OBJC(ownerPtr) delegate];990[ThreadUtilities performOnMainThreadWaiting:YES block:^(){991992window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow993ownerWindow:owner994styleBits:styleBits995frameRect:frameRect996contentView:contentView];997// the window is released is CPlatformWindow.nativeDispose()998999if (window) [window.nsWindow retain];1000}];10011002JNF_COCOA_EXIT(env);10031004return ptr_to_jlong(window ? window.nsWindow : nil);1005}10061007/*1008* Class: sun_lwawt_macosx_CPlatformWindow1009* Method: nativeSetNSWindowStyleBits1010* Signature: (JII)V1011*/1012JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowStyleBits1013(JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)1014{1015JNF_COCOA_ENTER(env);10161017NSWindow *nsWindow = OBJC(windowPtr);1018[ThreadUtilities performOnMainThreadWaiting:NO block:^(){10191020AWTWindow *window = (AWTWindow*)[nsWindow delegate];10211022// scans the bit field, and only updates the values requested by the mask1023// (this implicitly handles the _CALLBACK_PROP_BITMASK case, since those are passive reads)1024jint newBits = window.styleBits & ~mask | bits & mask;10251026BOOL resized = NO;10271028// Check for a change to the full window content view option.1029// The content view must be resized first, otherwise the window will be resized to fit the existing1030// content view.1031if (IS(mask, FULL_WINDOW_CONTENT)) {1032if (IS(newBits, FULL_WINDOW_CONTENT) != IS(window.styleBits, FULL_WINDOW_CONTENT)) {1033NSRect frame = [nsWindow frame];1034NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:newBits];1035NSRect screenContentRect = [NSWindow contentRectForFrameRect:frame styleMask:styleMask];1036NSRect contentFrame = NSMakeRect(screenContentRect.origin.x - frame.origin.x,1037screenContentRect.origin.y - frame.origin.y,1038screenContentRect.size.width,1039screenContentRect.size.height);1040nsWindow.contentView.frame = contentFrame;1041resized = YES;1042}1043}10441045// resets the NSWindow's style mask if the mask intersects any of those bits1046if (mask & MASK(_STYLE_PROP_BITMASK)) {1047[nsWindow setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];1048}10491050// calls methods on NSWindow to change other properties, based on the mask1051if (mask & MASK(_METHOD_PROP_BITMASK)) {1052[window setPropertiesForStyleBits:newBits mask:mask];1053}10541055window.styleBits = newBits;10561057if (resized) {1058[window _deliverMoveResizeEvent];1059}1060}];10611062JNF_COCOA_EXIT(env);1063}10641065/*1066* Class: sun_lwawt_macosx_CPlatformWindow1067* Method: nativeSetNSWindowMenuBar1068* Signature: (JJ)V1069*/1070JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMenuBar1071(JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)1072{1073JNF_COCOA_ENTER(env);10741075NSWindow *nsWindow = OBJC(windowPtr);1076CMenuBar *menuBar = OBJC(menuBarPtr);1077[ThreadUtilities performOnMainThreadWaiting:NO block:^(){10781079AWTWindow *window = (AWTWindow*)[nsWindow delegate];10801081if ([nsWindow isKeyWindow]) {1082[window.javaMenuBar deactivate];1083}10841085window.javaMenuBar = menuBar;10861087CMenuBar* actualMenuBar = menuBar;1088if (actualMenuBar == nil) {1089actualMenuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];1090}10911092if ([nsWindow isKeyWindow]) {1093[CMenuBar activate:actualMenuBar modallyDisabled:NO];1094}1095}];10961097JNF_COCOA_EXIT(env);1098}10991100/*1101* Class: sun_lwawt_macosx_CPlatformWindow1102* Method: nativeGetNSWindowInsets1103* Signature: (J)Ljava/awt/Insets;1104*/1105JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowInsets1106(JNIEnv *env, jclass clazz, jlong windowPtr)1107{1108jobject ret = NULL;11091110JNF_COCOA_ENTER(env);11111112NSWindow *nsWindow = OBJC(windowPtr);1113__block NSRect contentRect = NSZeroRect;1114__block NSRect frame = NSZeroRect;11151116[ThreadUtilities performOnMainThreadWaiting:YES block:^(){11171118frame = [nsWindow frame];1119contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[nsWindow styleMask]];1120}];11211122jint top = (jint)(frame.size.height - contentRect.size.height);1123jint left = (jint)(contentRect.origin.x - frame.origin.x);1124jint bottom = (jint)(contentRect.origin.y - frame.origin.y);1125jint right = (jint)(frame.size.width - (contentRect.size.width + left));11261127static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");1128static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");1129ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);11301131JNF_COCOA_EXIT(env);1132return ret;1133}11341135/*1136* Class: sun_lwawt_macosx_CPlatformWindow1137* Method: nativeSetNSWindowBounds1138* Signature: (JDDDD)V1139*/1140JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds1141(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)1142{1143JNF_COCOA_ENTER(env);11441145NSRect jrect = NSMakeRect(originX, originY, width, height);11461147// TODO: not sure we need displayIfNeeded message in our view1148NSWindow *nsWindow = OBJC(windowPtr);1149[ThreadUtilities performOnMainThreadWaiting:NO block:^(){11501151AWTWindow *window = (AWTWindow*)[nsWindow delegate];11521153NSRect rect = ConvertNSScreenRect(NULL, jrect);1154[window constrainSize:&rect.size];11551156[nsWindow setFrame:rect display:YES];11571158// only start tracking events if pointer is above the toplevel1159// TODO: should post an Entered event if YES.1160NSPoint mLocation = [NSEvent mouseLocation];1161[nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];11621163// ensure we repaint the whole window after the resize operation1164// (this will also re-enable screen updates, which were disabled above)1165// TODO: send PaintEvent1166}];11671168JNF_COCOA_EXIT(env);1169}11701171/*1172* Class: sun_lwawt_macosx_CPlatformWindow1173* Method: nativeSetNSWindowMinMax1174* Signature: (JDDDD)V1175*/1176JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax1177(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)1178{1179JNF_COCOA_ENTER(env);11801181if (minW < 1) minW = 1;1182if (minH < 1) minH = 1;1183if (maxW < 1) maxW = 1;1184if (maxH < 1) maxH = 1;11851186NSWindow *nsWindow = OBJC(windowPtr);1187[ThreadUtilities performOnMainThreadWaiting:NO block:^(){11881189AWTWindow *window = (AWTWindow*)[nsWindow delegate];11901191NSSize min = { minW, minH };1192NSSize max = { maxW, maxH };11931194[window constrainSize:&min];1195[window constrainSize:&max];11961197window.javaMinSize = min;1198window.javaMaxSize = max;1199[window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];1200}];12011202JNF_COCOA_EXIT(env);1203}12041205/*1206* Class: sun_lwawt_macosx_CPlatformWindow1207* Method: nativePushNSWindowToBack1208* Signature: (J)V1209*/1210JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack1211(JNIEnv *env, jclass clazz, jlong windowPtr)1212{1213JNF_COCOA_ENTER(env);12141215NSWindow *nsWindow = OBJC(windowPtr);1216[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1217[nsWindow orderBack:nil];1218// Order parent windows1219AWTWindow *awtWindow = (AWTWindow*)[nsWindow delegate];1220while (awtWindow.ownerWindow != nil) {1221awtWindow = awtWindow.ownerWindow;1222if ([AWTWindow isJavaPlatformWindowVisible:awtWindow.nsWindow]) {1223[awtWindow.nsWindow orderBack:nil];1224}1225}1226// Order child windows1227[(AWTWindow*)[nsWindow delegate] orderChildWindows:NO];1228}];12291230JNF_COCOA_EXIT(env);1231}12321233/*1234* Class: sun_lwawt_macosx_CPlatformWindow1235* Method: nativePushNSWindowToFront1236* Signature: (J)V1237*/1238JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront1239(JNIEnv *env, jclass clazz, jlong windowPtr)1240{1241JNF_COCOA_ENTER(env);12421243NSWindow *nsWindow = OBJC(windowPtr);1244[ThreadUtilities performOnMainThreadWaiting:NO block:^(){12451246if (![nsWindow isKeyWindow]) {1247[nsWindow makeKeyAndOrderFront:nsWindow];1248} else {1249[nsWindow orderFront:nsWindow];1250}1251}];12521253JNF_COCOA_EXIT(env);1254}12551256/*1257* Class: sun_lwawt_macosx_CPlatformWindow1258* Method: nativeSetNSWindowTitle1259* Signature: (JLjava/lang/String;)V1260*/1261JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTitle1262(JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)1263{1264JNF_COCOA_ENTER(env);12651266NSWindow *nsWindow = OBJC(windowPtr);1267[nsWindow performSelectorOnMainThread:@selector(setTitle:)1268withObject:JNFJavaToNSString(env, jtitle)1269waitUntilDone:NO];12701271JNF_COCOA_EXIT(env);1272}12731274/*1275* Class: sun_lwawt_macosx_CPlatformWindow1276* Method: nativeRevalidateNSWindowShadow1277* Signature: (J)V1278*/1279JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow1280(JNIEnv *env, jclass clazz, jlong windowPtr)1281{1282JNF_COCOA_ENTER(env);12831284NSWindow *nsWindow = OBJC(windowPtr);1285[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1286[nsWindow invalidateShadow];1287}];12881289JNF_COCOA_EXIT(env);1290}12911292/*1293* Class: sun_lwawt_macosx_CPlatformWindow1294* Method: nativeScreenOn_AppKitThread1295* Signature: (J)I1296*/1297JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeScreenOn_1AppKitThread1298(JNIEnv *env, jclass clazz, jlong windowPtr)1299{1300jint ret = 0;13011302JNF_COCOA_ENTER(env);1303AWT_ASSERT_APPKIT_THREAD;13041305NSWindow *nsWindow = OBJC(windowPtr);1306NSDictionary *props = [[nsWindow screen] deviceDescription];1307ret = [[props objectForKey:@"NSScreenNumber"] intValue];13081309JNF_COCOA_EXIT(env);13101311return ret;1312}13131314/*1315* Class: sun_lwawt_macosx_CPlatformWindow1316* Method: nativeSetNSWindowMinimizedIcon1317* Signature: (JJ)V1318*/1319JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinimizedIcon1320(JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)1321{1322JNF_COCOA_ENTER(env);13231324NSWindow *nsWindow = OBJC(windowPtr);1325NSImage *image = OBJC(nsImagePtr);1326[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1327[nsWindow setMiniwindowImage:image];1328}];13291330JNF_COCOA_EXIT(env);1331}13321333/*1334* Class: sun_lwawt_macosx_CPlatformWindow1335* Method: nativeSetNSWindowRepresentedFilename1336* Signature: (JLjava/lang/String;)V1337*/1338JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRepresentedFilename1339(JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)1340{1341JNF_COCOA_ENTER(env);13421343NSWindow *nsWindow = OBJC(windowPtr);1344NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];1345[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1346[nsWindow setRepresentedURL:url];1347}];13481349JNF_COCOA_EXIT(env);1350}13511352/*1353* Class: sun_lwawt_macosx_CPlatformWindow1354* Method: nativeGetTopmostPlatformWindowUnderMouse1355* Signature: (J)V1356*/1357JNIEXPORT jobject1358JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse1359(JNIEnv *env, jclass clazz)1360{1361__block jobject topmostWindowUnderMouse = nil;13621363JNF_COCOA_ENTER(env);13641365[ThreadUtilities performOnMainThreadWaiting:YES block:^{1366AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];1367if (awtWindow != nil) {1368topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];1369}1370}];13711372JNF_COCOA_EXIT(env);13731374return topmostWindowUnderMouse;1375}13761377/*1378* Class: sun_lwawt_macosx_CPlatformWindow1379* Method: nativeSynthesizeMouseEnteredExitedEvents1380* Signature: ()V1381*/1382JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__1383(JNIEnv *env, jclass clazz)1384{1385JNF_COCOA_ENTER(env);13861387[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1388[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];1389}];13901391JNF_COCOA_EXIT(env);1392}13931394/*1395* Class: sun_lwawt_macosx_CPlatformWindow1396* Method: nativeSynthesizeMouseEnteredExitedEvents1397* Signature: (JI)V1398*/1399JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__JI1400(JNIEnv *env, jclass clazz, jlong windowPtr, jint eventType)1401{1402JNF_COCOA_ENTER(env);14031404if (eventType == NSMouseEntered || eventType == NSMouseExited) {1405NSWindow *nsWindow = OBJC(windowPtr);14061407[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1408[AWTWindow synthesizeMouseEnteredExitedEvents:nsWindow withType:eventType];1409}];1410} else {1411[JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];1412}14131414JNF_COCOA_EXIT(env);1415}14161417/*1418* Class: sun_lwawt_macosx_CPlatformWindow1419* Method: _toggleFullScreenMode1420* Signature: (J)V1421*/1422JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow__1toggleFullScreenMode1423(JNIEnv *env, jobject peer, jlong windowPtr)1424{1425JNF_COCOA_ENTER(env);14261427NSWindow *nsWindow = OBJC(windowPtr);1428SEL toggleFullScreenSelector = @selector(toggleFullScreen:);1429if (![nsWindow respondsToSelector:toggleFullScreenSelector]) return;14301431[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1432[nsWindow performSelector:toggleFullScreenSelector withObject:nil];1433}];14341435JNF_COCOA_EXIT(env);1436}14371438JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled1439(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)1440{1441JNF_COCOA_ENTER(env);14421443NSWindow *nsWindow = OBJC(windowPtr);1444[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1445AWTWindow *window = (AWTWindow*)[nsWindow delegate];14461447[window setEnabled: isEnabled];1448}];14491450JNF_COCOA_EXIT(env);1451}14521453JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeDispose1454(JNIEnv *env, jclass clazz, jlong windowPtr)1455{1456JNF_COCOA_ENTER(env);14571458NSWindow *nsWindow = OBJC(windowPtr);1459[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1460AWTWindow *window = (AWTWindow*)[nsWindow delegate];14611462if ([AWTWindow lastKeyWindow] == window) {1463[AWTWindow setLastKeyWindow: nil];1464}14651466// AWTWindow holds a reference to the NSWindow in its nsWindow1467// property. Unsetting the delegate allows it to be deallocated1468// which releases the reference. This, in turn, allows the window1469// itself be deallocated.1470[nsWindow setDelegate: nil];14711472[window release];1473}];14741475JNF_COCOA_EXIT(env);1476}14771478JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeEnterFullScreenMode1479(JNIEnv *env, jclass clazz, jlong windowPtr)1480{1481JNF_COCOA_ENTER(env);14821483NSWindow *nsWindow = OBJC(windowPtr);1484[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1485AWTWindow *window = (AWTWindow*)[nsWindow delegate];1486NSNumber* screenID = [AWTWindow getNSWindowDisplayID_AppKitThread: nsWindow];1487CGDirectDisplayID aID = [screenID intValue];14881489if (CGDisplayCapture(aID) == kCGErrorSuccess) {1490// remove window decoration1491NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];1492[nsWindow setStyleMask:(styleMask & ~NSTitledWindowMask) | NSBorderlessWindowMask];14931494int shieldLevel = CGShieldingWindowLevel();1495window.preFullScreenLevel = [nsWindow level];1496[nsWindow setLevel: shieldLevel];14971498NSRect screenRect = [[nsWindow screen] frame];1499[nsWindow setFrame:screenRect display:YES];1500} else {1501[JNFException raise:[ThreadUtilities getJNIEnv]1502as:kRuntimeException1503reason:"Failed to enter full screen."];1504}1505}];15061507JNF_COCOA_EXIT(env);1508}15091510JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeExitFullScreenMode1511(JNIEnv *env, jclass clazz, jlong windowPtr)1512{1513JNF_COCOA_ENTER(env);15141515NSWindow *nsWindow = OBJC(windowPtr);1516[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1517AWTWindow *window = (AWTWindow*)[nsWindow delegate];1518NSNumber* screenID = [AWTWindow getNSWindowDisplayID_AppKitThread: nsWindow];1519CGDirectDisplayID aID = [screenID intValue];15201521if (CGDisplayRelease(aID) == kCGErrorSuccess) {1522NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];1523[nsWindow setStyleMask:styleMask];1524[nsWindow setLevel: window.preFullScreenLevel];15251526// GraphicsDevice takes care of restoring pre full screen bounds1527} else {1528[JNFException raise:[ThreadUtilities getJNIEnv]1529as:kRuntimeException1530reason:"Failed to exit full screen."];1531}1532}];15331534JNF_COCOA_EXIT(env);1535}1536#endif1537153815391540