Path: blob/jdk8u272-b10-aarch32-20201026/jdk/src/macosx/native/sun/awt/AWTWindow.m
83406 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#import <Cocoa/Cocoa.h>26#import <JavaNativeFoundation/JavaNativeFoundation.h>27#import <JavaRuntimeSupport/JavaRuntimeSupport.h>2829#import "sun_lwawt_macosx_CPlatformWindow.h"30#import "com_apple_eawt_event_GestureHandler.h"31#import "com_apple_eawt_FullScreenHandler.h"32#import "ApplicationDelegate.h"3334#import "AWTWindow.h"35#import "AWTView.h"36#import "CMenu.h"37#import "CMenuBar.h"38#import "LWCToolkit.h"39#import "GeomUtilities.h"40#import "ThreadUtilities.h"41#import "OSVersion.h"4243#define MASK(KEY) \44(sun_lwawt_macosx_CPlatformWindow_ ## KEY)4546#define IS(BITS, KEY) \47((BITS & MASK(KEY)) != 0)4849#define SET(BITS, KEY, VALUE) \50BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)5152static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");5354// Cocoa windowDidBecomeKey/windowDidResignKey notifications55// doesn't provide information about "opposite" window, so we56// have to do a bit of tracking. This variable points to a window57// which had been the key window just before a new key window58// was set. It would be nil if the new key window isn't an AWT59// window or the app currently has no key window.60static AWTWindow* lastKeyWindow = nil;6162// --------------------------------------------------------------63// NSWindow/NSPanel descendants implementation64#define AWT_NS_WINDOW_IMPLEMENTATION \65- (id) initWithDelegate:(AWTWindow *)delegate \66frameRect:(NSRect)contectRect \67styleMask:(NSUInteger)styleMask \68contentView:(NSView *)view \69{ \70self = [super initWithContentRect:contectRect \71styleMask:styleMask \72backing:NSBackingStoreBuffered \73defer:NO]; \74\75if (self == nil) return nil; \76\77[self setDelegate:delegate]; \78[self setContentView:view]; \79[self setInitialFirstResponder:view]; \80[self setReleasedWhenClosed:NO]; \81[self setPreservesContentDuringLiveResize:YES]; \82\83return self; \84} \85\86/* NSWindow overrides */ \87- (BOOL) canBecomeKeyWindow { \88return [(AWTWindow*)[self delegate] canBecomeKeyWindow]; \89} \90\91- (BOOL) canBecomeMainWindow { \92return [(AWTWindow*)[self delegate] canBecomeMainWindow]; \93} \94\95- (BOOL) worksWhenModal { \96return [(AWTWindow*)[self delegate] worksWhenModal]; \97} \98\99- (void)sendEvent:(NSEvent *)event { \100[(AWTWindow*)[self delegate] sendEvent:event]; \101[super sendEvent:event]; \102}103104@implementation AWTWindow_Normal105AWT_NS_WINDOW_IMPLEMENTATION106107// Gesture support108- (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {109AWT_ASSERT_APPKIT_THREAD;110111JNIEnv *env = [ThreadUtilities getJNIEnv];112jobject platformWindow = [((AWTWindow *)self.delegate).javaPlatformWindow jObjectWithEnv:env];113if (platformWindow != NULL) {114// extract the target AWT Window object out of the CPlatformWindow115static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");116jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);117if (awtWindow != NULL) {118// translate the point into Java coordinates119NSPoint loc = [event locationInWindow];120loc.y = [self frame].size.height - loc.y;121122// send up to the GestureHandler to recursively dispatch on the AWT event thread123static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");124static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");125JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);126(*env)->DeleteLocalRef(env, awtWindow);127}128(*env)->DeleteLocalRef(env, platformWindow);129}130}131132- (void)beginGestureWithEvent:(NSEvent *)event {133[self postGesture:event134as:com_apple_eawt_event_GestureHandler_PHASE135a:-1.0136b:0.0];137}138139- (void)endGestureWithEvent:(NSEvent *)event {140[self postGesture:event141as:com_apple_eawt_event_GestureHandler_PHASE142a:1.0143b:0.0];144}145146- (void)magnifyWithEvent:(NSEvent *)event {147[self postGesture:event148as:com_apple_eawt_event_GestureHandler_MAGNIFY149a:[event magnification]150b:0.0];151}152153- (void)rotateWithEvent:(NSEvent *)event {154[self postGesture:event155as:com_apple_eawt_event_GestureHandler_ROTATE156a:[event rotation]157b:0.0];158}159160- (void)swipeWithEvent:(NSEvent *)event {161[self postGesture:event162as:com_apple_eawt_event_GestureHandler_SWIPE163a:[event deltaX]164b:[event deltaY]];165}166167@end168@implementation AWTWindow_Panel169AWT_NS_WINDOW_IMPLEMENTATION170@end171// END of NSWindow/NSPanel descendants implementation172// --------------------------------------------------------------173174175@implementation AWTWindow176177@synthesize nsWindow;178@synthesize javaPlatformWindow;179@synthesize javaMenuBar;180@synthesize javaMinSize;181@synthesize javaMaxSize;182@synthesize styleBits;183@synthesize isEnabled;184@synthesize ownerWindow;185@synthesize preFullScreenLevel;186@synthesize isMinimizing;187188- (void) updateMinMaxSize:(BOOL)resizable {189if (resizable) {190[self.nsWindow setMinSize:self.javaMinSize];191[self.nsWindow setMaxSize:self.javaMaxSize];192} else {193NSRect currentFrame = [self.nsWindow frame];194[self.nsWindow setMinSize:currentFrame.size];195[self.nsWindow setMaxSize:currentFrame.size];196}197}198199// creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits200+ (NSUInteger) styleMaskForStyleBits:(jint)styleBits {201NSUInteger type = 0;202if (IS(styleBits, DECORATED)) {203type |= NSTitledWindowMask;204if (IS(styleBits, CLOSEABLE)) type |= NSClosableWindowMask;205if (IS(styleBits, MINIMIZABLE)) type |= NSMiniaturizableWindowMask;206if (IS(styleBits, RESIZABLE)) type |= NSResizableWindowMask;207if (IS(styleBits, FULL_WINDOW_CONTENT)) type |= NSFullSizeContentViewWindowMask;208} else {209type |= NSBorderlessWindowMask;210}211212if (IS(styleBits, TEXTURED)) type |= NSTexturedBackgroundWindowMask;213if (IS(styleBits, UNIFIED)) type |= NSUnifiedTitleAndToolbarWindowMask;214if (IS(styleBits, UTILITY)) type |= NSUtilityWindowMask;215if (IS(styleBits, HUD)) type |= NSHUDWindowMask;216if (IS(styleBits, SHEET)) type |= NSDocModalWindowMask;217if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;218219return type;220}221222// updates _METHOD_PROP_BITMASK based properties on the window223- (void) setPropertiesForStyleBits:(jint)bits mask:(jint)mask {224if (IS(mask, RESIZABLE)) {225BOOL resizable = IS(bits, RESIZABLE);226[self updateMinMaxSize:resizable];227[self.nsWindow setShowsResizeIndicator:resizable];228// Zoom button should be disabled, if the window is not resizable,229// otherwise button should be restored to initial state.230BOOL zoom = resizable && IS(bits, ZOOMABLE);231[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:zoom];232}233234if (IS(mask, HAS_SHADOW)) {235[self.nsWindow setHasShadow:IS(bits, HAS_SHADOW)];236}237238if (IS(mask, ZOOMABLE)) {239[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:IS(bits, ZOOMABLE)];240}241242if (IS(mask, ALWAYS_ON_TOP)) {243[self.nsWindow setLevel:IS(bits, ALWAYS_ON_TOP) ? NSFloatingWindowLevel : NSNormalWindowLevel];244}245246if (IS(mask, HIDES_ON_DEACTIVATE)) {247[self.nsWindow setHidesOnDeactivate:IS(bits, HIDES_ON_DEACTIVATE)];248}249250if (IS(mask, DRAGGABLE_BACKGROUND)) {251[self.nsWindow setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];252}253254if (IS(mask, DOCUMENT_MODIFIED)) {255[self.nsWindow setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];256}257258if (IS(mask, FULLSCREENABLE) && [self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {259if (IS(bits, FULLSCREENABLE)) {260[self.nsWindow setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];261} else {262[self.nsWindow setCollectionBehavior:NSWindowCollectionBehaviorDefault];263}264}265266if (IS(mask, TRANSPARENT_TITLE_BAR) && [self.nsWindow respondsToSelector:@selector(setTitlebarAppearsTransparent:)]) {267[self.nsWindow setTitlebarAppearsTransparent:IS(bits, TRANSPARENT_TITLE_BAR)];268}269}270271- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow272ownerWindow:owner273styleBits:(jint)bits274frameRect:(NSRect)rect275contentView:(NSView *)view276{277AWT_ASSERT_APPKIT_THREAD;278279NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];280NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];281if (contentRect.size.width <= 0.0) {282contentRect.size.width = 1.0;283}284if (contentRect.size.height <= 0.0) {285contentRect.size.height = 1.0;286}287288self = [super init];289290if (self == nil) return nil; // no hope291292if (IS(bits, UTILITY) ||293IS(bits, NONACTIVATING) ||294IS(bits, HUD) ||295IS(bits, HIDES_ON_DEACTIVATE))296{297self.nsWindow = [[AWTWindow_Panel alloc] initWithDelegate:self298frameRect:contentRect299styleMask:styleMask300contentView:view];301}302else303{304// These windows will appear in the window list in the dock icon menu305self.nsWindow = [[AWTWindow_Normal alloc] initWithDelegate:self306frameRect:contentRect307styleMask:styleMask308contentView:view];309}310311if (self.nsWindow == nil) return nil; // no hope either312[self.nsWindow release]; // the property retains the object already313314self.isEnabled = YES;315self.isMinimizing = NO;316self.javaPlatformWindow = platformWindow;317self.styleBits = bits;318self.ownerWindow = owner;319[self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];320321if (IS(self.styleBits, IS_POPUP)) {322[self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];323}324325return self;326}327328+ (BOOL) isAWTWindow:(NSWindow *)window {329return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];330}331332// Retrieves the list of possible window layers (levels)333+ (NSArray*) getWindowLayers {334static NSArray *windowLayers;335static dispatch_once_t token;336337// Initialize the list of possible window layers338dispatch_once(&token, ^{339// The layers are ordered from front to back, (i.e. the toppest one is the first)340windowLayers = [NSArray arrayWithObjects:341[NSNumber numberWithInt:CGWindowLevelForKey(kCGPopUpMenuWindowLevelKey)],342[NSNumber numberWithInt:CGWindowLevelForKey(kCGFloatingWindowLevelKey)],343[NSNumber numberWithInt:CGWindowLevelForKey(kCGNormalWindowLevelKey)],344nil345];346[windowLayers retain];347});348return windowLayers;349}350351// returns id for the topmost window under mouse352+ (NSInteger) getTopmostWindowUnderMouseID {353NSInteger result = -1;354355NSArray *windowLayers = [AWTWindow getWindowLayers];356// Looking for the window under mouse starting from the toppest layer357for (NSNumber *layer in windowLayers) {358result = [AWTWindow getTopmostWindowUnderMouseIDImpl:[layer integerValue]];359if (result != -1) {360break;361}362}363return result;364}365366+ (NSInteger) getTopmostWindowUnderMouseIDImpl:(NSInteger)windowLayer {367NSInteger result = -1;368369NSRect screenRect = [[NSScreen mainScreen] frame];370NSPoint nsMouseLocation = [NSEvent mouseLocation];371CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);372373NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);374375for (NSDictionary *window in windows) {376NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];377if (layer == windowLayer) {378CGRect rect;379CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);380if (CGRectContainsPoint(rect, cgMouseLocation)) {381result = [[window objectForKey:(id)kCGWindowNumber] integerValue];382break;383}384}385}386[windows release];387return result;388}389390// checks that this window is under the mouse cursor and this point is not overlapped by others windows391- (BOOL) isTopmostWindowUnderMouse {392return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];393}394395+ (AWTWindow *) getTopmostWindowUnderMouse {396NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];397NSWindow *window;398399NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];400401while ((window = [windowEnumerator nextObject]) != nil) {402if ([window windowNumber] == topmostWindowUnderMouseID) {403BOOL isAWTWindow = [AWTWindow isAWTWindow: window];404return isAWTWindow ? (AWTWindow *) [window delegate] : nil;405}406}407return nil;408}409410+ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {411412NSPoint screenLocation = [NSEvent mouseLocation];413NSPoint windowLocation = [window convertScreenToBase: screenLocation];414int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;415416NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType417location: windowLocation418modifierFlags: modifierFlags419timestamp: 0420windowNumber: [window windowNumber]421context: nil422eventNumber: 0423trackingNumber: 0424userData: nil425];426427[[window contentView] deliverJavaMouseEvent: mouseEvent];428}429430+ (void) synthesizeMouseEnteredExitedEventsForAllWindows {431432NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];433NSArray *windows = [NSApp windows];434NSWindow *window;435436NSEnumerator *windowEnumerator = [windows objectEnumerator];437while ((window = [windowEnumerator nextObject]) != nil) {438if ([AWTWindow isAWTWindow: window]) {439BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);440BOOL mouseIsOver = [[window contentView] mouseIsOver];441if (isUnderMouse && !mouseIsOver) {442[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];443} else if (!isUnderMouse && mouseIsOver) {444[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];445}446}447}448}449450+ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {451AWT_ASSERT_APPKIT_THREAD;452NSScreen *screen = [window screen];453NSDictionary *deviceDescription = [screen deviceDescription];454return [deviceDescription objectForKey:@"NSScreenNumber"];455}456457- (void) dealloc {458AWT_ASSERT_APPKIT_THREAD;459460JNIEnv *env = [ThreadUtilities getJNIEnvUncached];461[self.javaPlatformWindow setJObject:nil withEnv:env];462self.javaPlatformWindow = nil;463self.nsWindow = nil;464self.ownerWindow = nil;465[super dealloc];466}467468// Tests whether window is blocked by modal dialog/window469- (BOOL) isBlocked {470BOOL isBlocked = NO;471472JNIEnv *env = [ThreadUtilities getJNIEnv];473jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];474if (platformWindow != NULL) {475static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isBlocked", "()Z");476isBlocked = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;477(*env)->DeleteLocalRef(env, platformWindow);478}479480return isBlocked;481}482483- (BOOL) isSimpleWindowOwnedByEmbeddedFrame {484BOOL isSimpleWindowOwnedByEmbeddedFrame = NO;485486JNIEnv *env = [ThreadUtilities getJNIEnv];487jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];488if (platformWindow != NULL) {489static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isSimpleWindowOwnedByEmbeddedFrame", "()Z");490isSimpleWindowOwnedByEmbeddedFrame = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;491(*env)->DeleteLocalRef(env, platformWindow);492}493494return isSimpleWindowOwnedByEmbeddedFrame;495}496497// Tests whether the corresponding Java platform window is visible or not498+ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {499BOOL isVisible = NO;500501if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {502AWTWindow *awtWindow = (AWTWindow *)[window delegate];503[AWTToolkit eventCountPlusPlus];504505JNIEnv *env = [ThreadUtilities getJNIEnv];506jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];507if (platformWindow != NULL) {508static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");509isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;510(*env)->DeleteLocalRef(env, platformWindow);511512}513}514return isVisible;515}516517// Orders window's childs based on the current focus state518- (void) orderChildWindows:(BOOL)focus {519AWT_ASSERT_APPKIT_THREAD;520521if (self.isMinimizing || [self isBlocked]) {522// Do not perform any ordering, if iconify is in progress523// or the window is blocked by a modal window524return;525}526527NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];528NSWindow *window;529while ((window = [windowEnumerator nextObject]) != nil) {530if ([AWTWindow isJavaPlatformWindowVisible:window]) {531AWTWindow *awtWindow = (AWTWindow *)[window delegate];532AWTWindow *owner = awtWindow.ownerWindow;533if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {534// Do not order 'always on top' windows535continue;536}537while (awtWindow.ownerWindow != nil) {538if (awtWindow.ownerWindow == self) {539if (focus) {540// Move the childWindow to floating level541// so it will appear in front of its542// parent which owns the focus543[window setLevel:NSFloatingWindowLevel];544} else {545// Focus owner has changed, move the childWindow546// back to normal window level547[window setLevel:NSNormalWindowLevel];548}549// The childWindow should be displayed in front of550// its nearest parentWindow551[window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];552break;553}554awtWindow = awtWindow.ownerWindow;555}556}557}558}559560// NSWindow overrides561- (BOOL) canBecomeKeyWindow {562AWT_ASSERT_APPKIT_THREAD;563return self.isEnabled && (IS(self.styleBits, SHOULD_BECOME_KEY) || [self isSimpleWindowOwnedByEmbeddedFrame]);564}565566- (BOOL) canBecomeMainWindow {567AWT_ASSERT_APPKIT_THREAD;568if (!self.isEnabled) {569// Native system can bring up the NSWindow to570// the top even if the window is not main.571// We should bring up the modal dialog manually572[AWTToolkit eventCountPlusPlus];573574JNIEnv *env = [ThreadUtilities getJNIEnv];575jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];576if (platformWindow != NULL) {577static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,578"checkBlockingAndOrder", "()Z");579JNFCallBooleanMethod(env, platformWindow, jm_checkBlockingAndOrder);580(*env)->DeleteLocalRef(env, platformWindow);581}582}583584return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);585}586587- (BOOL) worksWhenModal {588AWT_ASSERT_APPKIT_THREAD;589return IS(self.styleBits, MODAL_EXCLUDED);590}591592593// NSWindowDelegate methods594595- (void) _deliverMoveResizeEvent {596AWT_ASSERT_APPKIT_THREAD;597598// deliver the event if this is a user-initiated live resize or as a side-effect599// of a Java initiated resize, because AppKit can override the bounds and force600// the bounds of the window to avoid the Dock or remain on screen.601[AWTToolkit eventCountPlusPlus];602JNIEnv *env = [ThreadUtilities getJNIEnv];603jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];604if (platformWindow == NULL) {605// TODO: create generic AWT assert606}607608NSRect frame = ConvertNSScreenRect(env, [self.nsWindow frame]);609610static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIIIZ)V");611JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,612(jint)frame.origin.x,613(jint)frame.origin.y,614(jint)frame.size.width,615(jint)frame.size.height,616(jboolean)[self.nsWindow inLiveResize]);617(*env)->DeleteLocalRef(env, platformWindow);618619[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];620}621622- (void)windowDidMove:(NSNotification *)notification {623AWT_ASSERT_APPKIT_THREAD;624625[self _deliverMoveResizeEvent];626}627628- (void)windowDidResize:(NSNotification *)notification {629AWT_ASSERT_APPKIT_THREAD;630631[self _deliverMoveResizeEvent];632}633634- (void)windowDidExpose:(NSNotification *)notification {635AWT_ASSERT_APPKIT_THREAD;636637[AWTToolkit eventCountPlusPlus];638// TODO: don't see this callback invoked anytime so we track639// window exposing in _setVisible:(BOOL)640}641642// Hides/shows window's childs during iconify/de-iconify operation643- (void) iconifyChildWindows:(BOOL)iconify {644AWT_ASSERT_APPKIT_THREAD;645646NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];647NSWindow *window;648while ((window = [windowEnumerator nextObject]) != nil) {649if ([AWTWindow isJavaPlatformWindowVisible:window]) {650AWTWindow *awtWindow = (AWTWindow *)[window delegate];651while (awtWindow.ownerWindow != nil) {652if (awtWindow.ownerWindow == self) {653if (iconify) {654[window orderOut:window];655} else {656[window orderFront:window];657}658break;659}660awtWindow = awtWindow.ownerWindow;661}662}663}664}665666- (void) _deliverIconify:(BOOL)iconify {667AWT_ASSERT_APPKIT_THREAD;668669[AWTToolkit eventCountPlusPlus];670JNIEnv *env = [ThreadUtilities getJNIEnv];671jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];672if (platformWindow != NULL) {673static JNF_MEMBER_CACHE(jm_deliverIconify, jc_CPlatformWindow, "deliverIconify", "(Z)V");674JNFCallVoidMethod(env, platformWindow, jm_deliverIconify, iconify);675(*env)->DeleteLocalRef(env, platformWindow);676}677}678679- (void)windowWillMiniaturize:(NSNotification *)notification {680AWT_ASSERT_APPKIT_THREAD;681682self.isMinimizing = YES;683684JNIEnv *env = [ThreadUtilities getJNIEnv];685jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];686if (platformWindow != NULL) {687static JNF_MEMBER_CACHE(jm_windowWillMiniaturize, jc_CPlatformWindow, "windowWillMiniaturize", "()V");688JNFCallVoidMethod(env, platformWindow, jm_windowWillMiniaturize);689(*env)->DeleteLocalRef(env, platformWindow);690}691// Excplicitly make myself a key window to avoid possible692// negative visual effects during iconify operation693[self.nsWindow makeKeyAndOrderFront:self.nsWindow];694[self iconifyChildWindows:YES];695}696697- (void)windowDidMiniaturize:(NSNotification *)notification {698AWT_ASSERT_APPKIT_THREAD;699700[self _deliverIconify:JNI_TRUE];701self.isMinimizing = NO;702}703704- (void)windowDidDeminiaturize:(NSNotification *)notification {705AWT_ASSERT_APPKIT_THREAD;706707[self _deliverIconify:JNI_FALSE];708[self iconifyChildWindows:NO];709}710711- (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {712//AWT_ASSERT_APPKIT_THREAD;713JNIEnv *env = [ThreadUtilities getJNIEnvUncached];714jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];715if (platformWindow != NULL) {716jobject oppositeWindow = [opposite.javaPlatformWindow jObjectWithEnv:env];717718static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(ZLsun/lwawt/macosx/CPlatformWindow;)V");719JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused, oppositeWindow);720(*env)->DeleteLocalRef(env, platformWindow);721(*env)->DeleteLocalRef(env, oppositeWindow);722}723}724725726- (void) windowDidBecomeKey: (NSNotification *) notification {727AWT_ASSERT_APPKIT_THREAD;728[AWTToolkit eventCountPlusPlus];729AWTWindow *opposite = [AWTWindow lastKeyWindow];730731// Finds appropriate menubar in our hierarchy,732AWTWindow *awtWindow = self;733while (awtWindow.ownerWindow != nil) {734awtWindow = awtWindow.ownerWindow;735}736737CMenuBar *menuBar = nil;738BOOL isDisabled = NO;739if ([awtWindow.nsWindow isVisible]){740menuBar = awtWindow.javaMenuBar;741isDisabled = !awtWindow.isEnabled;742}743744if (menuBar == nil) {745menuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];746isDisabled = NO;747}748749[CMenuBar activate:menuBar modallyDisabled:isDisabled];750751[AWTWindow setLastKeyWindow:nil];752753[self _deliverWindowFocusEvent:YES oppositeWindow: opposite];754[self orderChildWindows:YES];755}756757- (void) windowDidResignKey: (NSNotification *) notification {758// TODO: check why sometimes at start is invoked *not* on AppKit main thread.759AWT_ASSERT_APPKIT_THREAD;760[AWTToolkit eventCountPlusPlus];761[self.javaMenuBar deactivate];762763// In theory, this might cause flickering if the window gaining focus764// has its own menu. However, I couldn't reproduce it on practice, so765// perhaps this is a non issue.766CMenuBar* defaultMenu = [[ApplicationDelegate sharedDelegate] defaultMenuBar];767if (defaultMenu != nil) {768[CMenuBar activate:defaultMenu modallyDisabled:NO];769}770771// the new key window772NSWindow *keyWindow = [NSApp keyWindow];773AWTWindow *opposite = nil;774if ([AWTWindow isAWTWindow: keyWindow]) {775opposite = (AWTWindow *)[keyWindow delegate];776[AWTWindow setLastKeyWindow: self];777} else {778[AWTWindow setLastKeyWindow: nil];779}780781[self _deliverWindowFocusEvent:NO oppositeWindow: opposite];782[self orderChildWindows:NO];783}784785- (void) windowDidBecomeMain: (NSNotification *) notification {786AWT_ASSERT_APPKIT_THREAD;787[AWTToolkit eventCountPlusPlus];788789JNIEnv *env = [ThreadUtilities getJNIEnv];790jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];791if (platformWindow != NULL) {792static JNF_MEMBER_CACHE(jm_windowDidBecomeMain, jc_CPlatformWindow, "windowDidBecomeMain", "()V");793JNFCallVoidMethod(env, platformWindow, jm_windowDidBecomeMain);794(*env)->DeleteLocalRef(env, platformWindow);795}796}797798- (BOOL)windowShouldClose:(id)sender {799AWT_ASSERT_APPKIT_THREAD;800[AWTToolkit eventCountPlusPlus];801JNIEnv *env = [ThreadUtilities getJNIEnv];802jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];803if (platformWindow != NULL) {804static JNF_MEMBER_CACHE(jm_deliverWindowClosingEvent, jc_CPlatformWindow, "deliverWindowClosingEvent", "()V");805JNFCallVoidMethod(env, platformWindow, jm_deliverWindowClosingEvent);806(*env)->DeleteLocalRef(env, platformWindow);807}808// The window will be closed (if allowed) as result of sending Java event809return NO;810}811812813- (void)_notifyFullScreenOp:(jint)op withEnv:(JNIEnv *)env {814static JNF_CLASS_CACHE(jc_FullScreenHandler, "com/apple/eawt/FullScreenHandler");815static JNF_STATIC_MEMBER_CACHE(jm_notifyFullScreenOperation, jc_FullScreenHandler, "handleFullScreenEventFromNative", "(Ljava/awt/Window;I)V");816static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");817jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];818if (platformWindow != NULL) {819jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);820if (awtWindow != NULL) {821JNFCallStaticVoidMethod(env, jm_notifyFullScreenOperation, awtWindow, op);822(*env)->DeleteLocalRef(env, awtWindow);823}824(*env)->DeleteLocalRef(env, platformWindow);825}826}827828829- (void)windowWillEnterFullScreen:(NSNotification *)notification {830static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");831JNIEnv *env = [ThreadUtilities getJNIEnv];832jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];833if (platformWindow != NULL) {834JNFCallVoidMethod(env, platformWindow, jm_windowWillEnterFullScreen);835[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_ENTER withEnv:env];836(*env)->DeleteLocalRef(env, platformWindow);837}838}839840- (void)windowDidEnterFullScreen:(NSNotification *)notification {841static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");842JNIEnv *env = [ThreadUtilities getJNIEnv];843jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];844if (platformWindow != NULL) {845JNFCallVoidMethod(env, platformWindow, jm_windowDidEnterFullScreen);846[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_ENTER withEnv:env];847(*env)->DeleteLocalRef(env, platformWindow);848}849[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];850}851852- (void)windowWillExitFullScreen:(NSNotification *)notification {853static JNF_MEMBER_CACHE(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");854JNIEnv *env = [ThreadUtilities getJNIEnv];855jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];856if (platformWindow != NULL) {857JNFCallVoidMethod(env, platformWindow, jm_windowWillExitFullScreen);858[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_EXIT withEnv:env];859(*env)->DeleteLocalRef(env, platformWindow);860}861}862863- (void)windowDidExitFullScreen:(NSNotification *)notification {864static JNF_MEMBER_CACHE(jm_windowDidExitFullScreen, jc_CPlatformWindow, "windowDidExitFullScreen", "()V");865JNIEnv *env = [ThreadUtilities getJNIEnv];866jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];867if (platformWindow != NULL) {868JNFCallVoidMethod(env, platformWindow, jm_windowDidExitFullScreen);869[self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_EXIT withEnv:env];870(*env)->DeleteLocalRef(env, platformWindow);871}872[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];873}874875- (void)sendEvent:(NSEvent *)event {876if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {877if ([self isBlocked]) {878// Move parent windows to front and make sure that a child window is displayed879// in front of its nearest parent.880if (self.ownerWindow != nil) {881JNIEnv *env = [ThreadUtilities getJNIEnvUncached];882jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];883if (platformWindow != NULL) {884static JNF_MEMBER_CACHE(jm_orderAboveSiblings, jc_CPlatformWindow, "orderAboveSiblings", "()V");885JNFCallVoidMethod(env,platformWindow, jm_orderAboveSiblings);886(*env)->DeleteLocalRef(env, platformWindow);887}888}889[self orderChildWindows:YES];890}891892NSPoint p = [NSEvent mouseLocation];893NSRect frame = [self.nsWindow frame];894NSRect contentRect = [self.nsWindow contentRectForFrameRect:frame];895896// Check if the click happened in the non-client area (title bar)897if (p.y >= (frame.origin.y + contentRect.size.height)) {898JNIEnv *env = [ThreadUtilities getJNIEnvUncached];899jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];900if (platformWindow != NULL) {901// Currently, no need to deliver the whole NSEvent.902static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");903JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);904(*env)->DeleteLocalRef(env, platformWindow);905}906}907}908}909910- (void)constrainSize:(NSSize*)size {911float minWidth = 0.f, minHeight = 0.f;912913if (IS(self.styleBits, DECORATED)) {914NSRect frame = [self.nsWindow frame];915NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self.nsWindow styleMask]];916917float top = frame.size.height - contentRect.size.height;918float left = contentRect.origin.x - frame.origin.x;919float bottom = contentRect.origin.y - frame.origin.y;920float right = frame.size.width - (contentRect.size.width + left);921922// Speculative estimation: 80 - enough for window decorations controls923minWidth += left + right + 80;924minHeight += top + bottom;925}926927minWidth = MAX(1.f, minWidth);928minHeight = MAX(1.f, minHeight);929930size->width = MAX(size->width, minWidth);931size->height = MAX(size->height, minHeight);932}933934- (void) setEnabled: (BOOL)flag {935self.isEnabled = flag;936937if (IS(self.styleBits, CLOSEABLE)) {938[[self.nsWindow standardWindowButton:NSWindowCloseButton] setEnabled: flag];939}940941if (IS(self.styleBits, MINIMIZABLE)) {942[[self.nsWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled: flag];943}944945if (IS(self.styleBits, ZOOMABLE)) {946[[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled: flag];947}948949if (IS(self.styleBits, RESIZABLE)) {950[self updateMinMaxSize:flag];951[self.nsWindow setShowsResizeIndicator:flag];952}953}954955+ (void) setLastKeyWindow:(AWTWindow *)window {956[window retain];957[lastKeyWindow release];958lastKeyWindow = window;959}960961+ (AWTWindow *) lastKeyWindow {962return lastKeyWindow;963}964965- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame {966return !NSEqualSizes(self.nsWindow.frame.size, newFrame.size);967}968969970@end // AWTWindow971972973/*974* Class: sun_lwawt_macosx_CPlatformWindow975* Method: nativeCreateNSWindow976* Signature: (JJIIII)J977*/978JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow979(JNIEnv *env, jobject obj, jlong contentViewPtr, jlong ownerPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)980{981__block AWTWindow *window = nil;982983JNF_COCOA_ENTER(env);984985JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];986NSView *contentView = OBJC(contentViewPtr);987NSRect frameRect = NSMakeRect(x, y, w, h);988AWTWindow *owner = [OBJC(ownerPtr) delegate];989[ThreadUtilities performOnMainThreadWaiting:YES block:^(){990991window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow992ownerWindow:owner993styleBits:styleBits994frameRect:frameRect995contentView:contentView];996// the window is released is CPlatformWindow.nativeDispose()997998if (window) [window.nsWindow retain];999}];10001001JNF_COCOA_EXIT(env);10021003return ptr_to_jlong(window ? window.nsWindow : nil);1004}10051006/*1007* Class: sun_lwawt_macosx_CPlatformWindow1008* Method: nativeSetNSWindowStyleBits1009* Signature: (JII)V1010*/1011JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowStyleBits1012(JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)1013{1014JNF_COCOA_ENTER(env);10151016NSWindow *nsWindow = OBJC(windowPtr);1017[ThreadUtilities performOnMainThreadWaiting:NO block:^(){10181019AWTWindow *window = (AWTWindow*)[nsWindow delegate];10201021// scans the bit field, and only updates the values requested by the mask1022// (this implicitly handles the _CALLBACK_PROP_BITMASK case, since those are passive reads)1023jint newBits = window.styleBits & ~mask | bits & mask;10241025BOOL resized = NO;10261027// Check for a change to the full window content view option.1028// The content view must be resized first, otherwise the window will be resized to fit the existing1029// content view.1030if (IS(mask, FULL_WINDOW_CONTENT)) {1031if (IS(newBits, FULL_WINDOW_CONTENT) != IS(window.styleBits, FULL_WINDOW_CONTENT)) {1032NSRect frame = [nsWindow frame];1033NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:newBits];1034NSRect screenContentRect = [NSWindow contentRectForFrameRect:frame styleMask:styleMask];1035NSRect contentFrame = NSMakeRect(screenContentRect.origin.x - frame.origin.x,1036screenContentRect.origin.y - frame.origin.y,1037screenContentRect.size.width,1038screenContentRect.size.height);1039nsWindow.contentView.frame = contentFrame;1040resized = YES;1041}1042}10431044// resets the NSWindow's style mask if the mask intersects any of those bits1045if (mask & MASK(_STYLE_PROP_BITMASK)) {1046[nsWindow setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];1047}10481049// calls methods on NSWindow to change other properties, based on the mask1050if (mask & MASK(_METHOD_PROP_BITMASK)) {1051[window setPropertiesForStyleBits:newBits mask:mask];1052}10531054window.styleBits = newBits;10551056if (resized) {1057[window _deliverMoveResizeEvent];1058}1059}];10601061JNF_COCOA_EXIT(env);1062}10631064/*1065* Class: sun_lwawt_macosx_CPlatformWindow1066* Method: nativeSetNSWindowMenuBar1067* Signature: (JJ)V1068*/1069JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMenuBar1070(JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)1071{1072JNF_COCOA_ENTER(env);10731074NSWindow *nsWindow = OBJC(windowPtr);1075CMenuBar *menuBar = OBJC(menuBarPtr);1076[ThreadUtilities performOnMainThreadWaiting:NO block:^(){10771078AWTWindow *window = (AWTWindow*)[nsWindow delegate];10791080if ([nsWindow isKeyWindow]) {1081[window.javaMenuBar deactivate];1082}10831084window.javaMenuBar = menuBar;10851086CMenuBar* actualMenuBar = menuBar;1087if (actualMenuBar == nil) {1088actualMenuBar = [[ApplicationDelegate sharedDelegate] defaultMenuBar];1089}10901091if ([nsWindow isKeyWindow]) {1092[CMenuBar activate:actualMenuBar modallyDisabled:NO];1093}1094}];10951096JNF_COCOA_EXIT(env);1097}10981099/*1100* Class: sun_lwawt_macosx_CPlatformWindow1101* Method: nativeGetNSWindowInsets1102* Signature: (J)Ljava/awt/Insets;1103*/1104JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowInsets1105(JNIEnv *env, jclass clazz, jlong windowPtr)1106{1107jobject ret = NULL;11081109JNF_COCOA_ENTER(env);11101111NSWindow *nsWindow = OBJC(windowPtr);1112__block NSRect contentRect = NSZeroRect;1113__block NSRect frame = NSZeroRect;11141115[ThreadUtilities performOnMainThreadWaiting:YES block:^(){11161117frame = [nsWindow frame];1118contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[nsWindow styleMask]];1119}];11201121jint top = (jint)(frame.size.height - contentRect.size.height);1122jint left = (jint)(contentRect.origin.x - frame.origin.x);1123jint bottom = (jint)(contentRect.origin.y - frame.origin.y);1124jint right = (jint)(frame.size.width - (contentRect.size.width + left));11251126static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");1127static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");1128ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);11291130JNF_COCOA_EXIT(env);1131return ret;1132}11331134/*1135* Class: sun_lwawt_macosx_CPlatformWindow1136* Method: nativeSetNSWindowBounds1137* Signature: (JDDDD)V1138*/1139JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds1140(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)1141{1142JNF_COCOA_ENTER(env);11431144NSRect jrect = NSMakeRect(originX, originY, width, height);11451146// TODO: not sure we need displayIfNeeded message in our view1147NSWindow *nsWindow = OBJC(windowPtr);1148[ThreadUtilities performOnMainThreadWaiting:NO block:^(){11491150AWTWindow *window = (AWTWindow*)[nsWindow delegate];11511152NSRect rect = ConvertNSScreenRect(NULL, jrect);1153[window constrainSize:&rect.size];11541155[nsWindow setFrame:rect display:YES];11561157// only start tracking events if pointer is above the toplevel1158// TODO: should post an Entered event if YES.1159NSPoint mLocation = [NSEvent mouseLocation];1160[nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];11611162// ensure we repaint the whole window after the resize operation1163// (this will also re-enable screen updates, which were disabled above)1164// TODO: send PaintEvent1165}];11661167JNF_COCOA_EXIT(env);1168}11691170/*1171* Class: sun_lwawt_macosx_CPlatformWindow1172* Method: nativeSetNSWindowMinMax1173* Signature: (JDDDD)V1174*/1175JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax1176(JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)1177{1178JNF_COCOA_ENTER(env);11791180if (minW < 1) minW = 1;1181if (minH < 1) minH = 1;1182if (maxW < 1) maxW = 1;1183if (maxH < 1) maxH = 1;11841185NSWindow *nsWindow = OBJC(windowPtr);1186[ThreadUtilities performOnMainThreadWaiting:NO block:^(){11871188AWTWindow *window = (AWTWindow*)[nsWindow delegate];11891190NSSize min = { minW, minH };1191NSSize max = { maxW, maxH };11921193[window constrainSize:&min];1194[window constrainSize:&max];11951196window.javaMinSize = min;1197window.javaMaxSize = max;1198[window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];1199}];12001201JNF_COCOA_EXIT(env);1202}12031204/*1205* Class: sun_lwawt_macosx_CPlatformWindow1206* Method: nativePushNSWindowToBack1207* Signature: (J)V1208*/1209JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack1210(JNIEnv *env, jclass clazz, jlong windowPtr)1211{1212JNF_COCOA_ENTER(env);12131214NSWindow *nsWindow = OBJC(windowPtr);1215[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1216[nsWindow orderBack:nil];1217// Order parent windows1218AWTWindow *awtWindow = (AWTWindow*)[nsWindow delegate];1219while (awtWindow.ownerWindow != nil) {1220awtWindow = awtWindow.ownerWindow;1221if ([AWTWindow isJavaPlatformWindowVisible:awtWindow.nsWindow]) {1222[awtWindow.nsWindow orderBack:nil];1223}1224}1225// Order child windows1226[(AWTWindow*)[nsWindow delegate] orderChildWindows:NO];1227}];12281229JNF_COCOA_EXIT(env);1230}12311232/*1233* Class: sun_lwawt_macosx_CPlatformWindow1234* Method: nativePushNSWindowToFront1235* Signature: (J)V1236*/1237JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront1238(JNIEnv *env, jclass clazz, jlong windowPtr)1239{1240JNF_COCOA_ENTER(env);12411242NSWindow *nsWindow = OBJC(windowPtr);1243[ThreadUtilities performOnMainThreadWaiting:NO block:^(){12441245if (![nsWindow isKeyWindow]) {1246[nsWindow makeKeyAndOrderFront:nsWindow];1247} else {1248[nsWindow orderFront:nsWindow];1249}1250}];12511252JNF_COCOA_EXIT(env);1253}12541255/*1256* Class: sun_lwawt_macosx_CPlatformWindow1257* Method: nativeSetNSWindowTitle1258* Signature: (JLjava/lang/String;)V1259*/1260JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTitle1261(JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)1262{1263JNF_COCOA_ENTER(env);12641265NSWindow *nsWindow = OBJC(windowPtr);1266[nsWindow performSelectorOnMainThread:@selector(setTitle:)1267withObject:JNFJavaToNSString(env, jtitle)1268waitUntilDone:NO];12691270JNF_COCOA_EXIT(env);1271}12721273/*1274* Class: sun_lwawt_macosx_CPlatformWindow1275* Method: nativeRevalidateNSWindowShadow1276* Signature: (J)V1277*/1278JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow1279(JNIEnv *env, jclass clazz, jlong windowPtr)1280{1281JNF_COCOA_ENTER(env);12821283NSWindow *nsWindow = OBJC(windowPtr);1284[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1285[nsWindow invalidateShadow];1286}];12871288JNF_COCOA_EXIT(env);1289}12901291/*1292* Class: sun_lwawt_macosx_CPlatformWindow1293* Method: nativeScreenOn_AppKitThread1294* Signature: (J)I1295*/1296JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeScreenOn_1AppKitThread1297(JNIEnv *env, jclass clazz, jlong windowPtr)1298{1299jint ret = 0;13001301JNF_COCOA_ENTER(env);1302AWT_ASSERT_APPKIT_THREAD;13031304NSWindow *nsWindow = OBJC(windowPtr);1305NSDictionary *props = [[nsWindow screen] deviceDescription];1306ret = [[props objectForKey:@"NSScreenNumber"] intValue];13071308JNF_COCOA_EXIT(env);13091310return ret;1311}13121313/*1314* Class: sun_lwawt_macosx_CPlatformWindow1315* Method: nativeSetNSWindowMinimizedIcon1316* Signature: (JJ)V1317*/1318JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinimizedIcon1319(JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)1320{1321JNF_COCOA_ENTER(env);13221323NSWindow *nsWindow = OBJC(windowPtr);1324NSImage *image = OBJC(nsImagePtr);1325[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1326[nsWindow setMiniwindowImage:image];1327}];13281329JNF_COCOA_EXIT(env);1330}13311332/*1333* Class: sun_lwawt_macosx_CPlatformWindow1334* Method: nativeSetNSWindowRepresentedFilename1335* Signature: (JLjava/lang/String;)V1336*/1337JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRepresentedFilename1338(JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)1339{1340JNF_COCOA_ENTER(env);13411342NSWindow *nsWindow = OBJC(windowPtr);1343NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];1344[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1345[nsWindow setRepresentedURL:url];1346}];13471348JNF_COCOA_EXIT(env);1349}13501351/*1352* Class: sun_lwawt_macosx_CPlatformWindow1353* Method: nativeGetTopmostPlatformWindowUnderMouse1354* Signature: (J)V1355*/1356JNIEXPORT jobject1357JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse1358(JNIEnv *env, jclass clazz)1359{1360__block jobject topmostWindowUnderMouse = nil;13611362JNF_COCOA_ENTER(env);13631364[ThreadUtilities performOnMainThreadWaiting:YES block:^{1365AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];1366if (awtWindow != nil) {1367topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];1368}1369}];13701371JNF_COCOA_EXIT(env);13721373return topmostWindowUnderMouse;1374}13751376/*1377* Class: sun_lwawt_macosx_CPlatformWindow1378* Method: nativeSynthesizeMouseEnteredExitedEvents1379* Signature: ()V1380*/1381JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__1382(JNIEnv *env, jclass clazz)1383{1384JNF_COCOA_ENTER(env);13851386[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1387[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];1388}];13891390JNF_COCOA_EXIT(env);1391}13921393/*1394* Class: sun_lwawt_macosx_CPlatformWindow1395* Method: nativeSynthesizeMouseEnteredExitedEvents1396* Signature: (JI)V1397*/1398JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents__JI1399(JNIEnv *env, jclass clazz, jlong windowPtr, jint eventType)1400{1401JNF_COCOA_ENTER(env);14021403if (eventType == NSMouseEntered || eventType == NSMouseExited) {1404NSWindow *nsWindow = OBJC(windowPtr);14051406[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1407[AWTWindow synthesizeMouseEnteredExitedEvents:nsWindow withType:eventType];1408}];1409} else {1410[JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];1411}14121413JNF_COCOA_EXIT(env);1414}14151416/*1417* Class: sun_lwawt_macosx_CPlatformWindow1418* Method: _toggleFullScreenMode1419* Signature: (J)V1420*/1421JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow__1toggleFullScreenMode1422(JNIEnv *env, jobject peer, jlong windowPtr)1423{1424JNF_COCOA_ENTER(env);14251426NSWindow *nsWindow = OBJC(windowPtr);1427SEL toggleFullScreenSelector = @selector(toggleFullScreen:);1428if (![nsWindow respondsToSelector:toggleFullScreenSelector]) return;14291430[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1431[nsWindow performSelector:toggleFullScreenSelector withObject:nil];1432}];14331434JNF_COCOA_EXIT(env);1435}14361437JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled1438(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)1439{1440JNF_COCOA_ENTER(env);14411442NSWindow *nsWindow = OBJC(windowPtr);1443[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1444AWTWindow *window = (AWTWindow*)[nsWindow delegate];14451446[window setEnabled: isEnabled];1447}];14481449JNF_COCOA_EXIT(env);1450}14511452JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeDispose1453(JNIEnv *env, jclass clazz, jlong windowPtr)1454{1455JNF_COCOA_ENTER(env);14561457NSWindow *nsWindow = OBJC(windowPtr);1458[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1459AWTWindow *window = (AWTWindow*)[nsWindow delegate];14601461if ([AWTWindow lastKeyWindow] == window) {1462[AWTWindow setLastKeyWindow: nil];1463}14641465// AWTWindow holds a reference to the NSWindow in its nsWindow1466// property. Unsetting the delegate allows it to be deallocated1467// which releases the reference. This, in turn, allows the window1468// itself be deallocated.1469[nsWindow setDelegate: nil];14701471[window release];1472}];14731474JNF_COCOA_EXIT(env);1475}14761477JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeEnterFullScreenMode1478(JNIEnv *env, jclass clazz, jlong windowPtr)1479{1480JNF_COCOA_ENTER(env);14811482NSWindow *nsWindow = OBJC(windowPtr);1483[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1484AWTWindow *window = (AWTWindow*)[nsWindow delegate];1485NSNumber* screenID = [AWTWindow getNSWindowDisplayID_AppKitThread: nsWindow];1486CGDirectDisplayID aID = [screenID intValue];14871488if (CGDisplayCapture(aID) == kCGErrorSuccess) {1489// remove window decoration1490NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];1491[nsWindow setStyleMask:(styleMask & ~NSTitledWindowMask) | NSBorderlessWindowMask];14921493int shieldLevel = CGShieldingWindowLevel();1494window.preFullScreenLevel = [nsWindow level];1495[nsWindow setLevel: shieldLevel];14961497NSRect screenRect = [[nsWindow screen] frame];1498[nsWindow setFrame:screenRect display:YES];1499} else {1500[JNFException raise:[ThreadUtilities getJNIEnv]1501as:kRuntimeException1502reason:"Failed to enter full screen."];1503}1504}];15051506JNF_COCOA_EXIT(env);1507}15081509JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeExitFullScreenMode1510(JNIEnv *env, jclass clazz, jlong windowPtr)1511{1512JNF_COCOA_ENTER(env);15131514NSWindow *nsWindow = OBJC(windowPtr);1515[ThreadUtilities performOnMainThreadWaiting:NO block:^(){1516AWTWindow *window = (AWTWindow*)[nsWindow delegate];1517NSNumber* screenID = [AWTWindow getNSWindowDisplayID_AppKitThread: nsWindow];1518CGDirectDisplayID aID = [screenID intValue];15191520if (CGDisplayRelease(aID) == kCGErrorSuccess) {1521NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];1522[nsWindow setStyleMask:styleMask];1523[nsWindow setLevel: window.preFullScreenLevel];15241525// GraphicsDevice takes care of restoring pre full screen bounds1526} else {1527[JNFException raise:[ThreadUtilities getJNIEnv]1528as:kRuntimeException1529reason:"Failed to exit full screen."];1530}1531}];15321533JNF_COCOA_EXIT(env);1534}1535153615371538