src/macosx/native/sun/awt/AWTWindow.m

Print this page




  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 
  44 #define MASK(KEY) \
  45     (sun_lwawt_macosx_CPlatformWindow_ ## KEY)
  46 
  47 #define IS(BITS, KEY) \
  48     ((BITS & MASK(KEY)) != 0)
  49 
  50 #define SET(BITS, KEY, VALUE) \
  51     BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)
  52 
  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;


 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(12, 12)];
 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, 11, 11));
 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 }


 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 


 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 @end // AWTWindow
 552 
 553 
 554 /*
 555  * Class:     sun_lwawt_macosx_CPlatformWindow
 556  * Method:    nativeCreateNSWindow
 557  * Signature: (JJIIII)J
 558  */
 559 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
 560 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
 561 {
 562     __block AWTWindow *window = nil;
 563 
 564 JNF_COCOA_ENTER(env);
 565 AWT_ASSERT_NOT_APPKIT_THREAD;
 566 
 567     JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
 568     NSView *contentView = OBJC(contentViewPtr);
 569     NSRect frameRect = NSMakeRect(x, y, w, h);
 570 


 686 
 687 /*
 688  * Class:     sun_lwawt_macosx_CPlatformWindow
 689  * Method:    nativeSetNSWindowBounds
 690  * Signature: (JDDDD)V
 691  */
 692 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
 693 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
 694 {
 695 JNF_COCOA_ENTER(env);
 696 AWT_ASSERT_NOT_APPKIT_THREAD;
 697 
 698     NSRect jrect = NSMakeRect(originX, originY, width, height);
 699 
 700     // TODO: not sure we need displayIfNeeded message in our view
 701     AWTWindow *window = OBJC(windowPtr);
 702     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 703         AWT_ASSERT_APPKIT_THREAD;
 704 
 705         NSRect rect = ConvertNSScreenRect(NULL, jrect);


 706         [window setFrame:rect display:YES];
 707 
 708         // only start tracking events if pointer is above the toplevel
 709         // TODO: should post an Entered event if YES.
 710         NSPoint mLocation = [NSEvent mouseLocation];
 711         [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 712 
 713         // ensure we repaint the whole window after the resize operation
 714         // (this will also re-enable screen updates, which were disabled above)
 715         // TODO: send PaintEvent
 716     }];
 717 
 718 JNF_COCOA_EXIT(env);
 719 }
 720 
 721 /*
 722  * Class:     sun_lwawt_macosx_CPlatformWindow
 723  * Method:    nativeSetNSWindowMinMax
 724  * Signature: (JDDDD)V
 725  */
 726 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
 727 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
 728 {
 729 JNF_COCOA_ENTER(env);
 730 AWT_ASSERT_NOT_APPKIT_THREAD;
 731 
 732     if (minW < 1) minW = 1;
 733     if (minH < 1) minH = 1;
 734     if (maxW < 1) maxW = 1;
 735     if (maxH < 1) maxH = 1;
 736 
 737     NSSize min = { minW, minH };
 738     NSSize max = { maxW, maxH };
 739 
 740     AWTWindow *window = OBJC(windowPtr);
 741     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 742         AWT_ASSERT_APPKIT_THREAD;
 743 






 744         window.javaMinSize = min;
 745         window.javaMaxSize = max;
 746         [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
 747     }];
 748 
 749 JNF_COCOA_EXIT(env);
 750 }
 751 
 752 /*
 753  * Class:     sun_lwawt_macosx_CPlatformWindow
 754  * Method:    nativePushNSWindowToBack
 755  * Signature: (J)V
 756  */
 757 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
 758 (JNIEnv *env, jclass clazz, jlong windowPtr)
 759 {
 760 JNF_COCOA_ENTER(env);
 761 AWT_ASSERT_NOT_APPKIT_THREAD;
 762 
 763     AWTWindow *window = OBJC(windowPtr);


 813 
 814 JNF_COCOA_EXIT(env);
 815 }
 816 
 817 /*
 818  * Class:     sun_lwawt_macosx_CPlatformWindow
 819  * Method:    nativeSetNSWindowAlpha
 820  * Signature: (JF)V
 821  */
 822 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowAlpha
 823 (JNIEnv *env, jclass clazz, jlong windowPtr, jfloat alpha)
 824 {
 825 JNF_COCOA_ENTER(env);
 826 AWT_ASSERT_NOT_APPKIT_THREAD;
 827 
 828     AWTWindow *window = OBJC(windowPtr);
 829     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 830         AWT_ASSERT_APPKIT_THREAD;
 831 
 832         [window setAlphaValue:alpha];
 833         [window.growBoxWindow setAlphaValue:alpha];
 834     }];
 835 
 836 JNF_COCOA_EXIT(env);
 837 }
 838 
 839 /*
 840  * Class:     sun_lwawt_macosx_CPlatformWindow
 841  * Method:    nativeRevalidateNSWindowShadow
 842  * Signature: (J)V
 843  */
 844 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow
 845 (JNIEnv *env, jclass clazz, jlong windowPtr)
 846 {
 847 JNF_COCOA_ENTER(env);
 848 AWT_ASSERT_NOT_APPKIT_THREAD;
 849 
 850     AWTWindow *window = OBJC(windowPtr);
 851     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 852         AWT_ASSERT_APPKIT_THREAD;
 853 




  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 #define MASK(KEY) \
  44     (sun_lwawt_macosx_CPlatformWindow_ ## KEY)
  45 
  46 #define IS(BITS, KEY) \
  47     ((BITS & MASK(KEY)) != 0)
  48 
  49 #define SET(BITS, KEY, VALUE) \
  50     BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)
  51 

  52 static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
  53 

















  54 @implementation AWTWindow
  55 
  56 @synthesize javaPlatformWindow;
  57 @synthesize javaMenuBar;

  58 @synthesize javaMinSize;
  59 @synthesize javaMaxSize;
  60 @synthesize styleBits;
  61 
  62 - (void) updateMinMaxSize:(BOOL)resizable {
  63     if (resizable) {
  64         [self setMinSize:self.javaMinSize];
  65         [self setMaxSize:self.javaMaxSize];
  66     } else {
  67         NSRect currentFrame = [self frame];
  68         [self setMinSize:currentFrame.size];
  69         [self setMaxSize:currentFrame.size];
  70     }
  71 }
  72 
  73 // creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits
  74 + (NSUInteger) styleMaskForStyleBits:(jint)styleBits {
  75     NSUInteger type = 0;
  76     if (IS(styleBits, DECORATED)) {
  77         type |= NSTitledWindowMask;


 117     }
 118 
 119     if (IS(mask, DRAGGABLE_BACKGROUND)) {
 120         [self setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];
 121     }
 122 
 123     if (IS(mask, DOCUMENT_MODIFIED)) {
 124         [self setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
 125     }
 126 
 127     if ([self respondsToSelector:@selector(toggleFullScreen:)]) {
 128         if (IS(mask, FULLSCREENABLE)) {
 129             [self setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
 130         } else {
 131             [self setCollectionBehavior:NSWindowCollectionBehaviorDefault];
 132         }
 133     }
 134 
 135 }
 136 


















 137 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
 138                     styleBits:(jint)bits
 139                     frameRect:(NSRect)rect
 140                   contentView:(NSView *)view
 141 {
 142 AWT_ASSERT_APPKIT_THREAD;
 143 
 144     NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
 145     NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
 146     if (contentRect.size.width <= 0.0) {
 147         contentRect.size.width = 1.0;
 148     }
 149     if (contentRect.size.height <= 0.0) {
 150         contentRect.size.height = 1.0;
 151     }
 152 
 153     self = [super initWithContentRect:contentRect
 154                             styleMask:styleMask
 155                               backing:NSBackingStoreBuffered
 156                                 defer:NO];
 157 
 158     if (self == nil) return nil; // no hope
 159 
 160     self.javaPlatformWindow = platformWindow;
 161     self.styleBits = bits;
 162     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 163 
 164     [self setDelegate:self];
 165     [self setContentView:view];
 166     [self setInitialFirstResponder:view];
 167     [self setReleasedWhenClosed:NO];
 168     [self setPreservesContentDuringLiveResize:YES];
 169 






















 170     return self;
 171 }
 172 
 173 - (void) dealloc {
 174 AWT_ASSERT_APPKIT_THREAD;
 175 
 176     JNIEnv *env = [ThreadUtilities getJNIEnv];
 177     [self.javaPlatformWindow setJObject:nil withEnv:env];

 178 
 179     [super dealloc];
 180 }
 181 
 182 
 183 // NSWindow overrides
 184 - (BOOL) canBecomeKeyWindow {
 185 AWT_ASSERT_APPKIT_THREAD;
 186     return IS(self.styleBits, SHOULD_BECOME_KEY);
 187 }
 188 
 189 - (BOOL) canBecomeMainWindow {
 190 AWT_ASSERT_APPKIT_THREAD;
 191     return IS(self.styleBits, SHOULD_BECOME_MAIN);
 192 }
 193 
 194 - (BOOL) worksWhenModal {
 195 AWT_ASSERT_APPKIT_THREAD;
 196     return IS(self.styleBits, MODAL_EXCLUDED);
 197 }


 243                     b:0.0];
 244 }
 245 
 246 - (void)rotateWithEvent:(NSEvent *)event {
 247     [self postGesture:event
 248                    as:com_apple_eawt_event_GestureHandler_ROTATE
 249                     a:[event rotation]
 250                     b:0.0];
 251 }
 252 
 253 - (void)swipeWithEvent:(NSEvent *)event {
 254     [self postGesture:event
 255                    as:com_apple_eawt_event_GestureHandler_SWIPE
 256                     a:[event deltaX]
 257                     b:[event deltaY]];
 258 }
 259 
 260 
 261 // NSWindowDelegate methods
 262 








 263 - (void) _deliverMoveResizeEvent {
 264 AWT_ASSERT_APPKIT_THREAD;
 265 
 266     // deliver the event if this is a user-initiated live resize or as a side-effect
 267     // of a Java initiated resize, because AppKit can override the bounds and force
 268     // the bounds of the window to avoid the Dock or remain on screen.
 269     [AWTToolkit eventCountPlusPlus];
 270     JNIEnv *env = [ThreadUtilities getJNIEnv];
 271     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 272     if (platformWindow == NULL) {
 273         // TODO: create generic AWT assert
 274     }
 275 


 276     NSRect frame = ConvertNSScreenRect(env, [self frame]);
 277 
 278     static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIII)V");
 279     JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,
 280                       (jint)frame.origin.x,
 281                       (jint)frame.origin.y,
 282                       (jint)frame.size.width,
 283                       (jint)frame.size.height);
 284     (*env)->DeleteLocalRef(env, platformWindow);
 285 }
 286 
 287 - (void)windowDidMove:(NSNotification *)notification {
 288 AWT_ASSERT_APPKIT_THREAD;
 289 
 290     [self _deliverMoveResizeEvent];
 291 }
 292 
 293 - (void)windowDidResize:(NSNotification *)notification {
 294 AWT_ASSERT_APPKIT_THREAD;
 295 


 460 }
 461 
 462 - (void)sendEvent:(NSEvent *)event {
 463         if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
 464 
 465             NSPoint p = [NSEvent mouseLocation];
 466             NSRect frame = [self frame];
 467             NSRect contentRect = [self contentRectForFrameRect:frame];
 468 
 469             // Check if the click happened in the non-client area (title bar)
 470             if (p.y >= (frame.origin.y + contentRect.size.height)) {
 471                 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 472                 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 473                 // Currently, no need to deliver the whole NSEvent.
 474                 static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
 475                 JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
 476             }
 477         }
 478         [super sendEvent:event];
 479 }
 480 
 481 - (void)constrainSize:(NSSize*)size {
 482     float minWidth = 0.f, minHeight = 0.f;
 483 
 484     if (IS(self.styleBits, DECORATED)) {
 485         NSRect frame = [self frame];
 486         NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self styleMask]];
 487 
 488         float top = frame.size.height - contentRect.size.height;
 489         float left = contentRect.origin.x - frame.origin.x;
 490         float bottom = contentRect.origin.y - frame.origin.y;
 491         float right = frame.size.width - (contentRect.size.width + left);
 492 
 493         // Speculative estimation: 80 - enough for window decorations controls
 494         minWidth += left + right + 80;
 495         minHeight += top + bottom;
 496     }
 497 
 498     minWidth = MAX(1.f, minWidth);
 499     minHeight = MAX(1.f, minHeight);
 500 
 501     size->width = MAX(size->width, minWidth);
 502     size->height = MAX(size->height, minHeight);
 503 }
 504 
 505 @end // AWTWindow
 506 
 507 
 508 /*
 509  * Class:     sun_lwawt_macosx_CPlatformWindow
 510  * Method:    nativeCreateNSWindow
 511  * Signature: (JJIIII)J
 512  */
 513 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
 514 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
 515 {
 516     __block AWTWindow *window = nil;
 517 
 518 JNF_COCOA_ENTER(env);
 519 AWT_ASSERT_NOT_APPKIT_THREAD;
 520 
 521     JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
 522     NSView *contentView = OBJC(contentViewPtr);
 523     NSRect frameRect = NSMakeRect(x, y, w, h);
 524 


 640 
 641 /*
 642  * Class:     sun_lwawt_macosx_CPlatformWindow
 643  * Method:    nativeSetNSWindowBounds
 644  * Signature: (JDDDD)V
 645  */
 646 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
 647 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
 648 {
 649 JNF_COCOA_ENTER(env);
 650 AWT_ASSERT_NOT_APPKIT_THREAD;
 651 
 652     NSRect jrect = NSMakeRect(originX, originY, width, height);
 653 
 654     // TODO: not sure we need displayIfNeeded message in our view
 655     AWTWindow *window = OBJC(windowPtr);
 656     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 657         AWT_ASSERT_APPKIT_THREAD;
 658 
 659         NSRect rect = ConvertNSScreenRect(NULL, jrect);
 660         [window constrainSize:&rect.size];
 661 
 662         [window setFrame:rect display:YES];
 663 
 664         // only start tracking events if pointer is above the toplevel
 665         // TODO: should post an Entered event if YES.
 666         NSPoint mLocation = [NSEvent mouseLocation];
 667         [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 668 
 669         // ensure we repaint the whole window after the resize operation
 670         // (this will also re-enable screen updates, which were disabled above)
 671         // TODO: send PaintEvent
 672     }];
 673 
 674 JNF_COCOA_EXIT(env);
 675 }
 676 
 677 /*
 678  * Class:     sun_lwawt_macosx_CPlatformWindow
 679  * Method:    nativeSetNSWindowMinMax
 680  * Signature: (JDDDD)V
 681  */
 682 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
 683 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
 684 {
 685 JNF_COCOA_ENTER(env);
 686 AWT_ASSERT_NOT_APPKIT_THREAD;
 687 
 688     if (minW < 1) minW = 1;
 689     if (minH < 1) minH = 1;
 690     if (maxW < 1) maxW = 1;
 691     if (maxH < 1) maxH = 1;
 692 



 693     AWTWindow *window = OBJC(windowPtr);
 694     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 695         AWT_ASSERT_APPKIT_THREAD;
 696 
 697         NSSize min = { minW, minH };
 698         NSSize max = { maxW, maxH };
 699 
 700         [window constrainSize:&min];
 701         [window constrainSize:&max];
 702 
 703         window.javaMinSize = min;
 704         window.javaMaxSize = max;
 705         [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
 706     }];
 707 
 708 JNF_COCOA_EXIT(env);
 709 }
 710 
 711 /*
 712  * Class:     sun_lwawt_macosx_CPlatformWindow
 713  * Method:    nativePushNSWindowToBack
 714  * Signature: (J)V
 715  */
 716 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
 717 (JNIEnv *env, jclass clazz, jlong windowPtr)
 718 {
 719 JNF_COCOA_ENTER(env);
 720 AWT_ASSERT_NOT_APPKIT_THREAD;
 721 
 722     AWTWindow *window = OBJC(windowPtr);


 772 
 773 JNF_COCOA_EXIT(env);
 774 }
 775 
 776 /*
 777  * Class:     sun_lwawt_macosx_CPlatformWindow
 778  * Method:    nativeSetNSWindowAlpha
 779  * Signature: (JF)V
 780  */
 781 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowAlpha
 782 (JNIEnv *env, jclass clazz, jlong windowPtr, jfloat alpha)
 783 {
 784 JNF_COCOA_ENTER(env);
 785 AWT_ASSERT_NOT_APPKIT_THREAD;
 786 
 787     AWTWindow *window = OBJC(windowPtr);
 788     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 789         AWT_ASSERT_APPKIT_THREAD;
 790 
 791         [window setAlphaValue:alpha];

 792     }];
 793 
 794 JNF_COCOA_EXIT(env);
 795 }
 796 
 797 /*
 798  * Class:     sun_lwawt_macosx_CPlatformWindow
 799  * Method:    nativeRevalidateNSWindowShadow
 800  * Signature: (J)V
 801  */
 802 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow
 803 (JNIEnv *env, jclass clazz, jlong windowPtr)
 804 {
 805 JNF_COCOA_ENTER(env);
 806 AWT_ASSERT_NOT_APPKIT_THREAD;
 807 
 808     AWTWindow *window = OBJC(windowPtr);
 809     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 810         AWT_ASSERT_APPKIT_THREAD;
 811