1 /*
   2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #import <Cocoa/Cocoa.h>
  27 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  28 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
  29 
  30 #import "sun_lwawt_macosx_CPlatformWindow.h"
  31 #import "com_apple_eawt_event_GestureHandler.h"
  32 #import "com_apple_eawt_FullScreenHandler.h"
  33 
  34 #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"
  42 
  43 static const float GROW_BOX_SIZE = 12.f;
  44 
  45 #define MASK(KEY) \
  46     (sun_lwawt_macosx_CPlatformWindow_ ## KEY)
  47 
  48 #define IS(BITS, KEY) \
  49     ((BITS & MASK(KEY)) != 0)
  50 
  51 #define SET(BITS, KEY, VALUE) \
  52     BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)
  53 
  54 static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
  55 
  56 @interface JavaResizeGrowBoxOverlayWindow : NSWindow { }
  57 
  58 @end
  59 
  60 @implementation JavaResizeGrowBoxOverlayWindow
  61 
  62 - (BOOL) accessibilityIsIgnored
  63 {
  64     return YES;
  65 }
  66 
  67 - (NSArray *)accessibilityChildrenAttribute
  68 {
  69     return nil;
  70 }
  71 @end
  72 
  73 @implementation AWTWindow
  74 
  75 @synthesize javaPlatformWindow;
  76 @synthesize javaMenuBar;
  77 @synthesize growBoxWindow;
  78 @synthesize javaMinSize;
  79 @synthesize javaMaxSize;
  80 @synthesize styleBits;
  81 
  82 - (void) updateMinMaxSize:(BOOL)resizable {
  83     if (resizable) {
  84         [self setMinSize:self.javaMinSize];
  85         [self setMaxSize:self.javaMaxSize];
  86     } else {
  87         NSRect currentFrame = [self frame];
  88         [self setMinSize:currentFrame.size];
  89         [self setMaxSize:currentFrame.size];
  90     }
  91 }
  92 
  93 // creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits
  94 + (NSUInteger) styleMaskForStyleBits:(jint)styleBits {
  95     NSUInteger type = 0;
  96     if (IS(styleBits, DECORATED)) {
  97         type |= NSTitledWindowMask;
  98         if (IS(styleBits, CLOSEABLE))   type |= NSClosableWindowMask;
  99         if (IS(styleBits, MINIMIZABLE)) type |= NSMiniaturizableWindowMask;
 100         if (IS(styleBits, RESIZABLE))   type |= NSResizableWindowMask;
 101     } else {
 102         type |= NSBorderlessWindowMask;
 103     }
 104 
 105     if (IS(styleBits, TEXTURED))      type |= NSTexturedBackgroundWindowMask;
 106     if (IS(styleBits, UNIFIED))       type |= NSUnifiedTitleAndToolbarWindowMask;
 107     if (IS(styleBits, UTILITY))       type |= NSUtilityWindowMask;
 108     if (IS(styleBits, HUD))           type |= NSHUDWindowMask;
 109     if (IS(styleBits, SHEET))         type |= NSDocModalWindowMask;
 110     if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;
 111 
 112     return type;
 113 }
 114 
 115 // updates _METHOD_PROP_BITMASK based properties on the window
 116 - (void) setPropertiesForStyleBits:(jint)bits mask:(jint)mask {
 117     if (IS(mask, RESIZABLE)) {
 118         BOOL resizable = IS(bits, RESIZABLE);
 119         [self updateMinMaxSize:resizable];
 120         [self setShowsResizeIndicator:resizable];
 121     }
 122 
 123     if (IS(mask, HAS_SHADOW)) {
 124         [self setHasShadow:IS(bits, HAS_SHADOW)];
 125     }
 126 
 127     if (IS(mask, ZOOMABLE)) {
 128         [[self standardWindowButton:NSWindowZoomButton] setEnabled:IS(bits, ZOOMABLE)];
 129     }
 130 
 131     if (IS(mask, ALWAYS_ON_TOP)) {
 132         [self setLevel:IS(bits, ALWAYS_ON_TOP) ? NSFloatingWindowLevel : NSNormalWindowLevel];
 133     }
 134 
 135     if (IS(mask, HIDES_ON_DEACTIVATE)) {
 136         [self setHidesOnDeactivate:IS(bits, HIDES_ON_DEACTIVATE)];
 137     }
 138 
 139     if (IS(mask, DRAGGABLE_BACKGROUND)) {
 140         [self setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];
 141     }
 142 
 143     if (IS(mask, DOCUMENT_MODIFIED)) {
 144         [self setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
 145     }
 146 
 147     if ([self respondsToSelector:@selector(toggleFullScreen:)]) {
 148         if (IS(mask, FULLSCREENABLE)) {
 149             [self setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
 150         } else {
 151             [self setCollectionBehavior:NSWindowCollectionBehaviorDefault];
 152         }
 153     }
 154 
 155 }
 156 
 157 - (BOOL) shouldShowGrowBox {
 158     return isSnowLeopardOrLower() && IS(self.styleBits, RESIZABLE);
 159 }
 160 
 161 - (NSImage *) createGrowBoxImage {
 162     NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(GROW_BOX_SIZE, GROW_BOX_SIZE)];
 163     JRSUIControlRef growBoxWidget = JRSUIControlCreate(FALSE);
 164     JRSUIControlSetWidget(growBoxWidget, kJRSUI_Widget_growBoxTextured);
 165     JRSUIControlSetWindowType(growBoxWidget, kJRSUI_WindowType_utility);
 166     JRSUIRendererRef renderer = JRSUIRendererCreate();
 167     [image lockFocus]; // sets current graphics context to that of the image
 168     JRSUIControlDraw(renderer, growBoxWidget, [[NSGraphicsContext currentContext] graphicsPort], CGRectMake(0, 1, GROW_BOX_SIZE - 1, GROW_BOX_SIZE - 1));
 169     [image unlockFocus];
 170     JRSUIRendererRelease(renderer);
 171     JRSUIControlRelease(growBoxWidget);
 172     return image;
 173 }
 174 
 175 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
 176                     styleBits:(jint)bits
 177                     frameRect:(NSRect)rect
 178                   contentView:(NSView *)view
 179 {
 180 AWT_ASSERT_APPKIT_THREAD;
 181 
 182     NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
 183     NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
 184     if (contentRect.size.width <= 0.0) {
 185         contentRect.size.width = 1.0;
 186     }
 187     if (contentRect.size.height <= 0.0) {
 188         contentRect.size.height = 1.0;
 189     }
 190 
 191     self = [super initWithContentRect:contentRect
 192                             styleMask:styleMask
 193                               backing:NSBackingStoreBuffered
 194                                 defer:NO];
 195 
 196     if (self == nil) return nil; // no hope
 197 
 198     self.javaPlatformWindow = platformWindow;
 199     self.styleBits = bits;
 200     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 201 
 202     [self setDelegate:self];
 203     [self setContentView:view];
 204     [self setInitialFirstResponder:view];
 205     [self setReleasedWhenClosed:NO];
 206     [self setPreservesContentDuringLiveResize:YES];
 207 
 208     if ([self shouldShowGrowBox]) {
 209         NSImage *growBoxImage = [self createGrowBoxImage];
 210         growBoxWindow = [[JavaResizeGrowBoxOverlayWindow alloc] initWithContentRect:NSMakeRect(0, 0, [growBoxImage size].width, [growBoxImage size].height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
 211         [self.growBoxWindow setIgnoresMouseEvents:YES];
 212         [self.growBoxWindow setOpaque:NO];
 213         [self.growBoxWindow setBackgroundColor:[NSColor clearColor]];
 214         [self.growBoxWindow setHasShadow:NO];
 215         [self.growBoxWindow setReleasedWhenClosed:NO];
 216 
 217         NSImageView *imageView = [[NSImageView alloc] initWithFrame:[self.growBoxWindow frame]];
 218         [imageView setEditable:NO];
 219         [imageView setAnimates:NO];
 220         [imageView setAllowsCutCopyPaste:NO];
 221         [self.growBoxWindow setContentView:imageView];
 222         [imageView setImage:growBoxImage];
 223         [growBoxImage release];
 224         [imageView release];
 225 
 226         [self addChildWindow:self.growBoxWindow ordered:NSWindowAbove];
 227         [self adjustGrowBoxWindow];
 228     } else growBoxWindow = nil;
 229 
 230     return self;
 231 }
 232 
 233 - (void) dealloc {
 234 AWT_ASSERT_APPKIT_THREAD;
 235 
 236     JNIEnv *env = [ThreadUtilities getJNIEnv];
 237     [self.javaPlatformWindow setJObject:nil withEnv:env];
 238     self.growBoxWindow = nil;
 239 
 240     [super dealloc];
 241 }
 242 
 243 
 244 // NSWindow overrides
 245 - (BOOL) canBecomeKeyWindow {
 246 AWT_ASSERT_APPKIT_THREAD;
 247     return IS(self.styleBits, SHOULD_BECOME_KEY);
 248 }
 249 
 250 - (BOOL) canBecomeMainWindow {
 251 AWT_ASSERT_APPKIT_THREAD;
 252     return IS(self.styleBits, SHOULD_BECOME_MAIN);
 253 }
 254 
 255 - (BOOL) worksWhenModal {
 256 AWT_ASSERT_APPKIT_THREAD;
 257     return IS(self.styleBits, MODAL_EXCLUDED);
 258 }
 259 
 260 
 261 // Gesture support
 262 - (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {
 263 AWT_ASSERT_APPKIT_THREAD;
 264 
 265     JNIEnv *env = [ThreadUtilities getJNIEnv];
 266     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 267     if (platformWindow != NULL) {
 268         // extract the target AWT Window object out of the CPlatformWindow
 269         static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
 270         jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
 271         if (awtWindow != NULL) {
 272             // translate the point into Java coordinates
 273             NSPoint loc = [event locationInWindow];
 274             loc.y = [self frame].size.height - loc.y;
 275 
 276             // send up to the GestureHandler to recursively dispatch on the AWT event thread
 277             static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");
 278             static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");
 279             JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
 280             (*env)->DeleteLocalRef(env, awtWindow);
 281         }
 282         (*env)->DeleteLocalRef(env, platformWindow);
 283     }
 284 }
 285 
 286 - (void)beginGestureWithEvent:(NSEvent *)event {
 287     [self postGesture:event
 288                    as:com_apple_eawt_event_GestureHandler_PHASE
 289                     a:-1.0
 290                     b:0.0];
 291 }
 292 
 293 - (void)endGestureWithEvent:(NSEvent *)event {
 294     [self postGesture:event
 295                    as:com_apple_eawt_event_GestureHandler_PHASE
 296                     a:1.0
 297                     b:0.0];
 298 }
 299 
 300 - (void)magnifyWithEvent:(NSEvent *)event {
 301     [self postGesture:event
 302                    as:com_apple_eawt_event_GestureHandler_MAGNIFY
 303                     a:[event magnification]
 304                     b:0.0];
 305 }
 306 
 307 - (void)rotateWithEvent:(NSEvent *)event {
 308     [self postGesture:event
 309                    as:com_apple_eawt_event_GestureHandler_ROTATE
 310                     a:[event rotation]
 311                     b:0.0];
 312 }
 313 
 314 - (void)swipeWithEvent:(NSEvent *)event {
 315     [self postGesture:event
 316                    as:com_apple_eawt_event_GestureHandler_SWIPE
 317                     a:[event deltaX]
 318                     b:[event deltaY]];
 319 }
 320 
 321 
 322 // NSWindowDelegate methods
 323 
 324 - (void) adjustGrowBoxWindow {
 325     if (self.growBoxWindow != nil) {
 326         NSRect parentRect = [self frame];
 327         parentRect.origin.x += (parentRect.size.width - [self.growBoxWindow frame].size.width);
 328         [self.growBoxWindow setFrameOrigin:parentRect.origin];
 329     }
 330 }
 331 
 332 - (void) _deliverMoveResizeEvent {
 333 AWT_ASSERT_APPKIT_THREAD;
 334 
 335     // deliver the event if this is a user-initiated live resize or as a side-effect
 336     // of a Java initiated resize, because AppKit can override the bounds and force
 337     // the bounds of the window to avoid the Dock or remain on screen.
 338     [AWTToolkit eventCountPlusPlus];
 339     JNIEnv *env = [ThreadUtilities getJNIEnv];
 340     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 341     if (platformWindow == NULL) {
 342         // TODO: create generic AWT assert
 343     }
 344 
 345     [self adjustGrowBoxWindow];
 346 
 347     NSRect frame = ConvertNSScreenRect(env, [self frame]);
 348 
 349     static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIII)V");
 350     JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,
 351                       (jint)frame.origin.x,
 352                       (jint)frame.origin.y,
 353                       (jint)frame.size.width,
 354                       (jint)frame.size.height);
 355     (*env)->DeleteLocalRef(env, platformWindow);
 356 }
 357 
 358 - (void)windowDidMove:(NSNotification *)notification {
 359 AWT_ASSERT_APPKIT_THREAD;
 360 
 361     [self _deliverMoveResizeEvent];
 362 }
 363 
 364 - (void)windowDidResize:(NSNotification *)notification {
 365 AWT_ASSERT_APPKIT_THREAD;
 366 
 367     [self _deliverMoveResizeEvent];
 368 }
 369 
 370 - (void)windowDidExpose:(NSNotification *)notification {
 371 AWT_ASSERT_APPKIT_THREAD;
 372 
 373     [AWTToolkit eventCountPlusPlus];
 374     // TODO: don't see this callback invoked anytime so we track
 375     // window exposing in _setVisible:(BOOL)
 376 }
 377 
 378 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)proposedFrame {
 379 AWT_ASSERT_APPKIT_THREAD;
 380 
 381     [AWTToolkit eventCountPlusPlus];
 382     JNIEnv *env = [ThreadUtilities getJNIEnv];
 383     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 384     if (platformWindow != NULL) {
 385         static JNF_MEMBER_CACHE(jm_deliverZoom, jc_CPlatformWindow, "deliverZoom", "(Z)V");
 386         JNFCallVoidMethod(env, platformWindow, jm_deliverZoom, ![window isZoomed]);
 387         (*env)->DeleteLocalRef(env, platformWindow);
 388     }
 389     return YES;
 390 }
 391 
 392 - (void) _deliverIconify:(BOOL)iconify {
 393 AWT_ASSERT_APPKIT_THREAD;
 394 
 395     [AWTToolkit eventCountPlusPlus];
 396     JNIEnv *env = [ThreadUtilities getJNIEnv];
 397     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 398     if (platformWindow != NULL) {
 399         static JNF_MEMBER_CACHE(jm_deliverIconify, jc_CPlatformWindow, "deliverIconify", "(Z)V");
 400         JNFCallVoidMethod(env, platformWindow, jm_deliverIconify, iconify);
 401         (*env)->DeleteLocalRef(env, platformWindow);
 402     }
 403 }
 404 
 405 - (void)windowDidMiniaturize:(NSNotification *)notification {
 406 AWT_ASSERT_APPKIT_THREAD;
 407 
 408     [self _deliverIconify:JNI_TRUE];
 409 }
 410 
 411 - (void)windowDidDeminiaturize:(NSNotification *)notification {
 412 AWT_ASSERT_APPKIT_THREAD;
 413 
 414     [self _deliverIconify:JNI_FALSE];
 415 }
 416 
 417 - (void) _deliverWindowFocusEvent:(BOOL)focused {
 418 //AWT_ASSERT_APPKIT_THREAD;
 419 
 420     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 421     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 422     if (platformWindow != NULL) {
 423         static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(Z)V");
 424         JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused);
 425         (*env)->DeleteLocalRef(env, platformWindow);
 426     }
 427 }
 428 
 429 
 430 - (void) windowDidBecomeKey: (NSNotification *) notification {
 431 AWT_ASSERT_APPKIT_THREAD;
 432     [AWTToolkit eventCountPlusPlus];
 433     [CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
 434     [self _deliverWindowFocusEvent:YES];
 435 }
 436 
 437 - (void) windowDidResignKey: (NSNotification *) notification {
 438     // TODO: check why sometimes at start is invoked *not* on AppKit main thread.
 439 AWT_ASSERT_APPKIT_THREAD;
 440     [AWTToolkit eventCountPlusPlus];
 441     [self.javaMenuBar deactivate];
 442     [self _deliverWindowFocusEvent:NO];
 443 }
 444 
 445 - (void) windowDidBecomeMain: (NSNotification *) notification {
 446 AWT_ASSERT_APPKIT_THREAD;
 447     [AWTToolkit eventCountPlusPlus];
 448 
 449     JNIEnv *env = [ThreadUtilities getJNIEnv];
 450     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 451     if (platformWindow != NULL) {
 452         static JNF_MEMBER_CACHE(jm_windowDidBecomeMain, jc_CPlatformWindow, "windowDidBecomeMain", "()V");
 453         JNFCallVoidMethod(env, platformWindow, jm_windowDidBecomeMain);
 454         (*env)->DeleteLocalRef(env, platformWindow);
 455     }
 456 }
 457 
 458 - (BOOL)windowShouldClose:(id)sender {
 459 AWT_ASSERT_APPKIT_THREAD;
 460     [AWTToolkit eventCountPlusPlus];
 461     JNIEnv *env = [ThreadUtilities getJNIEnv];
 462     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 463     if (platformWindow != NULL) {
 464         static JNF_MEMBER_CACHE(jm_deliverWindowClosingEvent, jc_CPlatformWindow, "deliverWindowClosingEvent", "()V");
 465         JNFCallVoidMethod(env, platformWindow, jm_deliverWindowClosingEvent);
 466         (*env)->DeleteLocalRef(env, platformWindow);
 467     }
 468     // The window will be closed (if allowed) as result of sending Java event
 469     return NO;
 470 }
 471 
 472 
 473 - (void)_notifyFullScreenOp:(jint)op withEnv:(JNIEnv *)env {
 474     static JNF_CLASS_CACHE(jc_FullScreenHandler, "com/apple/eawt/FullScreenHandler");
 475     static JNF_STATIC_MEMBER_CACHE(jm_notifyFullScreenOperation, jc_FullScreenHandler, "handleFullScreenEventFromNative", "(Ljava/awt/Window;I)V");
 476     static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
 477     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 478     if (platformWindow != NULL) {
 479         jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
 480         if (awtWindow != NULL) {
 481             JNFCallStaticVoidMethod(env, jm_notifyFullScreenOperation, awtWindow, op);
 482             (*env)->DeleteLocalRef(env, awtWindow);
 483         }
 484         (*env)->DeleteLocalRef(env, platformWindow);
 485     }
 486 }
 487 
 488 
 489 - (void)windowWillEnterFullScreen:(NSNotification *)notification {
 490     static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
 491     JNIEnv *env = [ThreadUtilities getJNIEnv];
 492     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 493     if (platformWindow != NULL) {
 494         JNFCallVoidMethod(env, platformWindow, jm_windowWillEnterFullScreen);
 495         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_ENTER withEnv:env];
 496         (*env)->DeleteLocalRef(env, platformWindow);
 497     }
 498 }
 499 
 500 - (void)windowDidEnterFullScreen:(NSNotification *)notification {
 501     static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");
 502     JNIEnv *env = [ThreadUtilities getJNIEnv];
 503     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 504     if (platformWindow != NULL) {
 505         JNFCallVoidMethod(env, platformWindow, jm_windowDidEnterFullScreen);
 506         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_ENTER withEnv:env];
 507         (*env)->DeleteLocalRef(env, platformWindow);
 508     }
 509 }
 510 
 511 - (void)windowWillExitFullScreen:(NSNotification *)notification {
 512     static JNF_MEMBER_CACHE(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");
 513     JNIEnv *env = [ThreadUtilities getJNIEnv];
 514     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 515     if (platformWindow != NULL) {
 516         JNFCallVoidMethod(env, platformWindow, jm_windowWillExitFullScreen);
 517         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_EXIT withEnv:env];
 518         (*env)->DeleteLocalRef(env, platformWindow);
 519     }
 520 }
 521 
 522 - (void)windowDidExitFullScreen:(NSNotification *)notification {
 523     static JNF_MEMBER_CACHE(jm_windowDidExitFullScreen, jc_CPlatformWindow, "windowDidExitFullScreen", "()V");
 524     JNIEnv *env = [ThreadUtilities getJNIEnv];
 525     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 526     if (platformWindow != NULL) {
 527         JNFCallVoidMethod(env, platformWindow, jm_windowDidExitFullScreen);
 528         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_EXIT withEnv:env];
 529         (*env)->DeleteLocalRef(env, platformWindow);
 530     }
 531 }
 532 
 533 - (void)sendEvent:(NSEvent *)event {
 534         if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
 535 
 536             NSPoint p = [NSEvent mouseLocation];
 537             NSRect frame = [self frame];
 538             NSRect contentRect = [self contentRectForFrameRect:frame];
 539 
 540             // Check if the click happened in the non-client area (title bar)
 541             if (p.y >= (frame.origin.y + contentRect.size.height)) {
 542                 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 543                 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 544                 // Currently, no need to deliver the whole NSEvent.
 545                 static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
 546                 JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
 547             }
 548         }
 549         [super sendEvent:event];
 550 }
 551 
 552 - (void)constrainSize:(NSSize*)size {
 553     float minWidth = 0.f, minHeight = 0.f;
 554 
 555     if (IS(self.styleBits, DECORATED)) {
 556         NSRect frame = [self frame];
 557         NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self styleMask]];
 558 
 559         float top = frame.size.height - contentRect.size.height;
 560         float left = contentRect.origin.x - frame.origin.x;
 561         float bottom = contentRect.origin.y - frame.origin.y;
 562         float right = frame.size.width - (contentRect.size.width + left);
 563 
 564         // Speculative estimation: 80 - enough for window decorations controls
 565         minWidth += left + right + 80;
 566         minHeight += top + bottom;
 567     }
 568 
 569     if ([self shouldShowGrowBox]) {
 570         minWidth = MAX(minWidth, GROW_BOX_SIZE);
 571         minHeight += GROW_BOX_SIZE;
 572     }
 573 
 574     minWidth = MAX(1.f, minWidth);
 575     minHeight = MAX(1.f, minHeight);
 576 
 577     size->width = MAX(size->width, minWidth);
 578     size->height = MAX(size->height, minHeight);
 579 }
 580 
 581 @end // AWTWindow
 582 
 583 
 584 /*
 585  * Class:     sun_lwawt_macosx_CPlatformWindow
 586  * Method:    nativeCreateNSWindow
 587  * Signature: (JJIIII)J
 588  */
 589 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
 590 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
 591 {
 592     __block AWTWindow *window = nil;
 593 
 594 JNF_COCOA_ENTER(env);
 595 AWT_ASSERT_NOT_APPKIT_THREAD;
 596 
 597     JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
 598     NSView *contentView = OBJC(contentViewPtr);
 599     NSRect frameRect = NSMakeRect(x, y, w, h);
 600 
 601     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
 602         AWT_ASSERT_APPKIT_THREAD;
 603 
 604         window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow
 605                                                   styleBits:styleBits
 606                                                   frameRect:frameRect
 607                                                 contentView:contentView];
 608 
 609         if (window) CFRetain(window);
 610         [window release]; // GC
 611     }];
 612 
 613 JNF_COCOA_EXIT(env);
 614 
 615     return ptr_to_jlong(window);
 616 }
 617 
 618 /*
 619  * Class:     sun_lwawt_macosx_CPlatformWindow
 620  * Method:    nativeSetNSWindowStyleBits
 621  * Signature: (JII)V
 622  */
 623 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowStyleBits
 624 (JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)
 625 {
 626 JNF_COCOA_ENTER(env);
 627 AWT_ASSERT_NOT_APPKIT_THREAD;
 628 
 629     AWTWindow *window = OBJC(windowPtr);
 630     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 631         AWT_ASSERT_APPKIT_THREAD;
 632 
 633         // scans the bit field, and only updates the values requested by the mask
 634         // (this implicity handles the _CALLBACK_PROP_BITMASK case, since those are passive reads)
 635         jint newBits = window.styleBits & ~mask | bits & mask;
 636 
 637         // resets the NSWindow's style mask if the mask intersects any of those bits
 638         if (mask & MASK(_STYLE_PROP_BITMASK)) {
 639             [window setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];
 640         }
 641 
 642         // calls methods on NSWindow to change other properties, based on the mask
 643         if (mask & MASK(_METHOD_PROP_BITMASK)) {
 644             [window setPropertiesForStyleBits:bits mask:mask];
 645         }
 646 
 647         window.styleBits = newBits;
 648     }];
 649 
 650 JNF_COCOA_EXIT(env);
 651 }
 652 
 653 /*
 654  * Class:     sun_lwawt_macosx_CPlatformWindow
 655  * Method:    nativeSetNSWindowMenuBar
 656  * Signature: (JJ)V
 657  */
 658 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMenuBar
 659 (JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)
 660 {
 661 JNF_COCOA_ENTER(env);
 662 AWT_ASSERT_NOT_APPKIT_THREAD;
 663 
 664     AWTWindow *window = OBJC(windowPtr);
 665     CMenuBar *menuBar = OBJC(menuBarPtr);
 666     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 667         AWT_ASSERT_APPKIT_THREAD;
 668 
 669         if ([window isKeyWindow]) [window.javaMenuBar deactivate];
 670         window.javaMenuBar = menuBar;
 671 
 672         // if ([self isKeyWindow]) {
 673         [CMenuBar activate:window.javaMenuBar modallyDisabled:NO];
 674         // }
 675     }];
 676 
 677 JNF_COCOA_EXIT(env);
 678 }
 679 
 680 /*
 681  * Class:     sun_lwawt_macosx_CPlatformWindow
 682  * Method:    nativeGetNSWindowInsets
 683  * Signature: (J)Ljava/awt/Insets;
 684  */
 685 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowInsets
 686 (JNIEnv *env, jclass clazz, jlong windowPtr)
 687 {
 688     jobject ret = NULL;
 689 
 690 JNF_COCOA_ENTER(env);
 691 AWT_ASSERT_NOT_APPKIT_THREAD;
 692 
 693     AWTWindow *window = OBJC(windowPtr);
 694     __block NSRect contentRect = NSZeroRect;
 695     __block NSRect frame = NSZeroRect;
 696 
 697     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
 698         AWT_ASSERT_APPKIT_THREAD;
 699 
 700         frame = [window frame];
 701         contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[window styleMask]];
 702     }];
 703 
 704     jint top = (jint)(frame.size.height - contentRect.size.height);
 705     jint left = (jint)(contentRect.origin.x - frame.origin.x);
 706     jint bottom = (jint)(contentRect.origin.y - frame.origin.y);
 707     jint right = (jint)(frame.size.width - (contentRect.size.width + left));
 708 
 709     static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
 710     static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
 711     ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);
 712 
 713 JNF_COCOA_EXIT(env);
 714     return ret;
 715 }
 716 
 717 /*
 718  * Class:     sun_lwawt_macosx_CPlatformWindow
 719  * Method:    nativeSetNSWindowBounds
 720  * Signature: (JDDDD)V
 721  */
 722 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
 723 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
 724 {
 725 JNF_COCOA_ENTER(env);
 726 AWT_ASSERT_NOT_APPKIT_THREAD;
 727 
 728     NSRect jrect = NSMakeRect(originX, originY, width, height);
 729 
 730     // TODO: not sure we need displayIfNeeded message in our view
 731     AWTWindow *window = OBJC(windowPtr);
 732     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 733         AWT_ASSERT_APPKIT_THREAD;
 734 
 735         NSRect rect = ConvertNSScreenRect(NULL, jrect);
 736         [window constrainSize:&rect.size];
 737 
 738         [window setFrame:rect display:YES];
 739 
 740         // only start tracking events if pointer is above the toplevel
 741         // TODO: should post an Entered event if YES.
 742         NSPoint mLocation = [NSEvent mouseLocation];
 743         [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 744 
 745         // ensure we repaint the whole window after the resize operation
 746         // (this will also re-enable screen updates, which were disabled above)
 747         // TODO: send PaintEvent
 748     }];
 749 
 750 JNF_COCOA_EXIT(env);
 751 }
 752 
 753 /*
 754  * Class:     sun_lwawt_macosx_CPlatformWindow
 755  * Method:    nativeSetNSWindowMinMax
 756  * Signature: (JDDDD)V
 757  */
 758 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
 759 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
 760 {
 761 JNF_COCOA_ENTER(env);
 762 AWT_ASSERT_NOT_APPKIT_THREAD;
 763 
 764     if (minW < 1) minW = 1;
 765     if (minH < 1) minH = 1;
 766     if (maxW < 1) maxW = 1;
 767     if (maxH < 1) maxH = 1;
 768 
 769     AWTWindow *window = OBJC(windowPtr);
 770     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 771         AWT_ASSERT_APPKIT_THREAD;
 772 
 773         NSSize min = { minW, minH };
 774         NSSize max = { maxW, maxH };
 775 
 776         [window constrainSize:&min];
 777         [window constrainSize:&max];
 778 
 779         window.javaMinSize = min;
 780         window.javaMaxSize = max;
 781         [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
 782     }];
 783 
 784 JNF_COCOA_EXIT(env);
 785 }
 786 
 787 /*
 788  * Class:     sun_lwawt_macosx_CPlatformWindow
 789  * Method:    nativePushNSWindowToBack
 790  * Signature: (J)V
 791  */
 792 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
 793 (JNIEnv *env, jclass clazz, jlong windowPtr)
 794 {
 795 JNF_COCOA_ENTER(env);
 796 AWT_ASSERT_NOT_APPKIT_THREAD;
 797 
 798     AWTWindow *window = OBJC(windowPtr);
 799     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 800         AWT_ASSERT_APPKIT_THREAD;
 801 
 802         [window orderBack:nil];
 803     }];
 804 
 805 JNF_COCOA_EXIT(env);
 806 }
 807 
 808 /*
 809  * Class:     sun_lwawt_macosx_CPlatformWindow
 810  * Method:    nativePushNSWindowToFront
 811  * Signature: (J)V
 812  */
 813 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront
 814 (JNIEnv *env, jclass clazz, jlong windowPtr)
 815 {
 816 JNF_COCOA_ENTER(env);
 817 AWT_ASSERT_NOT_APPKIT_THREAD;
 818 
 819     AWTWindow *window = OBJC(windowPtr);
 820     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 821         AWT_ASSERT_APPKIT_THREAD;
 822 
 823         if (![window isKeyWindow]) {
 824             [window makeKeyAndOrderFront:window];
 825         } else {
 826             [window orderFront:window];
 827         }
 828     }];
 829 
 830 JNF_COCOA_EXIT(env);
 831 }
 832 
 833 /*
 834  * Class:     sun_lwawt_macosx_CPlatformWindow
 835  * Method:    nativeSetNSWindowTitle
 836  * Signature: (JLjava/lang/String;)V
 837  */
 838 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTitle
 839 (JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)
 840 {
 841 JNF_COCOA_ENTER(env);
 842 AWT_ASSERT_NOT_APPKIT_THREAD;
 843 
 844     AWTWindow *window = OBJC(windowPtr);
 845     [window performSelectorOnMainThread:@selector(setTitle:)
 846                               withObject:JNFJavaToNSString(env, jtitle)
 847                            waitUntilDone:NO];
 848 
 849 JNF_COCOA_EXIT(env);
 850 }
 851 
 852 /*
 853  * Class:     sun_lwawt_macosx_CPlatformWindow
 854  * Method:    nativeSetNSWindowAlpha
 855  * Signature: (JF)V
 856  */
 857 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowAlpha
 858 (JNIEnv *env, jclass clazz, jlong windowPtr, jfloat alpha)
 859 {
 860 JNF_COCOA_ENTER(env);
 861 AWT_ASSERT_NOT_APPKIT_THREAD;
 862 
 863     AWTWindow *window = OBJC(windowPtr);
 864     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 865         AWT_ASSERT_APPKIT_THREAD;
 866 
 867         [window setAlphaValue:alpha];
 868         [window.growBoxWindow setAlphaValue:alpha];
 869     }];
 870 
 871 JNF_COCOA_EXIT(env);
 872 }
 873 
 874 /*
 875  * Class:     sun_lwawt_macosx_CPlatformWindow
 876  * Method:    nativeRevalidateNSWindowShadow
 877  * Signature: (J)V
 878  */
 879 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow
 880 (JNIEnv *env, jclass clazz, jlong windowPtr)
 881 {
 882 JNF_COCOA_ENTER(env);
 883 AWT_ASSERT_NOT_APPKIT_THREAD;
 884 
 885     AWTWindow *window = OBJC(windowPtr);
 886     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 887         AWT_ASSERT_APPKIT_THREAD;
 888 
 889         [window invalidateShadow];
 890     }];
 891 
 892 JNF_COCOA_EXIT(env);
 893 }
 894 
 895 /*
 896  * Class:     sun_lwawt_macosx_CPlatformWindow
 897  * Method:    nativeScreenOn_AppKitThread
 898  * Signature: (J)I
 899  */
 900 JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeScreenOn_1AppKitThread
 901 (JNIEnv *env, jclass clazz, jlong windowPtr)
 902 {
 903     jint ret = 0;
 904 
 905 JNF_COCOA_ENTER(env);
 906 AWT_ASSERT_APPKIT_THREAD;
 907 
 908     AWTWindow *window = OBJC(windowPtr);
 909     NSDictionary *props = [[window screen] deviceDescription];
 910     ret = [[props objectForKey:@"NSScreenNumber"] intValue];
 911 
 912 JNF_COCOA_EXIT(env);
 913 
 914     return ret;
 915 }
 916 
 917 /*
 918  * Class:     sun_lwawt_macosx_CPlatformWindow
 919  * Method:    nativeSetNSWindowMinimizedIcon
 920  * Signature: (JJ)V
 921  */
 922 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinimizedIcon
 923 (JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)
 924 {
 925 JNF_COCOA_ENTER(env);
 926 AWT_ASSERT_NOT_APPKIT_THREAD;
 927 
 928     AWTWindow *window = OBJC(windowPtr);
 929     NSImage *image = OBJC(nsImagePtr);
 930     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 931         AWT_ASSERT_APPKIT_THREAD;
 932 
 933         [window setMiniwindowImage:image];
 934     }];
 935 
 936 JNF_COCOA_EXIT(env);
 937 }
 938 
 939 /*
 940  * Class:     sun_lwawt_macosx_CPlatformWindow
 941  * Method:    nativeSetNSWindowRepresentedFilename
 942  * Signature: (JLjava/lang/String;)V
 943  */
 944 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRepresentedFilename
 945 (JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)
 946 {
 947 JNF_COCOA_ENTER(env);
 948 AWT_ASSERT_NOT_APPKIT_THREAD;
 949 
 950     AWTWindow *window = OBJC(windowPtr);
 951     NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];
 952     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 953         AWT_ASSERT_APPKIT_THREAD;
 954 
 955         [window setRepresentedURL:url];
 956     }];
 957 
 958 JNF_COCOA_EXIT(env);
 959 }
 960 
 961 /*
 962  * Class:     sun_lwawt_macosx_CPlatformWindow
 963  * Method:    nativeSetNSWindowSecurityWarningPositioning
 964  * Signature: (JDDFF)V
 965  */
 966 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
 967 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
 968 {
 969 JNF_COCOA_ENTER(env);
 970 AWT_ASSERT_NOT_APPKIT_THREAD;
 971 
 972     [JNFException raise:env as:kRuntimeException reason:"unimplemented"];
 973 
 974 JNF_COCOA_EXIT(env);
 975 }
 976 
 977 /*
 978  * Class:     sun_lwawt_macosx_CPlatformWindow
 979  * Method:    nativeGetScreenNSWindowIsOn_AppKitThread
 980  * Signature: (J)I
 981  */
 982 JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetScreenNSWindowIsOn_1AppKitThread
 983 (JNIEnv *env, jclass clazz, jlong windowPtr)
 984 {
 985     jint index = -1;
 986 
 987 JNF_COCOA_ENTER(env);
 988 AWT_ASSERT_APPKIT_THREAD;
 989 
 990     AWTWindow *window = OBJC(windowPtr);
 991     NSScreen* screen = [window screen];
 992 
 993     //+++gdb NOTE: This is using a linear search of the screens. If it should
 994     //  prove to be a bottleneck, this can definitely be improved. However,
 995     //  many screens should prove to be the exception, rather than the rule.
 996     NSArray* screens = [NSScreen screens];
 997     NSUInteger i;
 998     for (i = 0; i < [screens count]; i++)
 999     {
1000         if ([[screens objectAtIndex:i] isEqualTo:screen])
1001         {
1002             index = i;
1003             break;
1004         }
1005     }
1006 
1007 JNF_COCOA_EXIT(env);
1008     return 1;
1009 }
1010 
1011 
1012 /*
1013  * Class:     sun_lwawt_macosx_CPlatformWindow
1014  * Method:    _toggleFullScreenMode
1015  * Signature: (J)V
1016  */
1017 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow__1toggleFullScreenMode
1018 (JNIEnv *env, jobject peer, jlong windowPtr)
1019 {
1020 JNF_COCOA_ENTER(env);
1021 
1022     AWTWindow *window = OBJC(windowPtr);
1023     SEL toggleFullScreenSelector = @selector(toggleFullScreen:);
1024     if (![window respondsToSelector:toggleFullScreenSelector]) return;
1025 
1026     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1027         [window performSelector:toggleFullScreenSelector withObject:nil];
1028     }];
1029 
1030 JNF_COCOA_EXIT(env);
1031 }
1032 
1033 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CMouseInfoPeer_nativeIsWindowUnderMouse
1034 (JNIEnv *env, jclass clazz, jlong windowPtr)
1035 {
1036     __block jboolean underMouse = JNI_FALSE;
1037 
1038 JNF_COCOA_ENTER(env);
1039 AWT_ASSERT_NOT_APPKIT_THREAD;
1040 
1041     AWTWindow *aWindow = OBJC(windowPtr);
1042     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
1043         AWT_ASSERT_APPKIT_THREAD;
1044 
1045         NSPoint pt = [aWindow mouseLocationOutsideOfEventStream];
1046         underMouse = [[aWindow contentView] hitTest:pt] != nil;
1047     }];
1048 
1049 JNF_COCOA_EXIT(env);
1050 
1051     return underMouse;
1052 }