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
|