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 #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 // --------------------------------------------------------------
55 // NSWindow/NSPanel descendants implementation
56 #define AWT_NS_WINDOW_IMPLEMENTATION \
57 - (id) initWithDelegate:(AWTWindow *)delegate \
58 frameRect:(NSRect)contectRect \
59 styleMask:(NSUInteger)styleMask \
60 contentView:(NSView *)view \
61 { \
62 self = [super initWithContentRect:contectRect \
63 styleMask:styleMask \
64 backing:NSBackingStoreBuffered \
65 defer:NO]; \
66 \
67 if (self == nil) return nil; \
68 \
69 [self setDelegate:delegate]; \
70 [self setContentView:view]; \
71 [self setInitialFirstResponder:view]; \
72 [self setReleasedWhenClosed:NO]; \
73 [self setPreservesContentDuringLiveResize:YES]; \
74 \
75 return self; \
76 } \
77 \
78 /* NSWindow overrides */ \
79 - (BOOL) canBecomeKeyWindow { \
80 return [(AWTWindow*)[self delegate] canBecomeKeyWindow]; \
81 } \
82 \
83 - (BOOL) canBecomeMainWindow { \
84 return [(AWTWindow*)[self delegate] canBecomeMainWindow]; \
85 } \
86 \
87 - (BOOL) worksWhenModal { \
88 return [(AWTWindow*)[self delegate] worksWhenModal]; \
89 } \
90 \
91 - (void)sendEvent:(NSEvent *)event { \
92 [(AWTWindow*)[self delegate] sendEvent:event]; \
93 [super sendEvent:event]; \
94 }
95
96 @implementation AWTWindow_Normal
97 AWT_NS_WINDOW_IMPLEMENTATION
98 @end
99 @implementation AWTWindow_Panel
100 AWT_NS_WINDOW_IMPLEMENTATION
101 @end
102 // END of NSWindow/NSPanel descendants implementation
103 // --------------------------------------------------------------
104
105
106 @implementation AWTWindow
107
108 @synthesize nsWindow;
109 @synthesize javaPlatformWindow;
110 @synthesize javaMenuBar;
111 @synthesize javaMinSize;
112 @synthesize javaMaxSize;
113 @synthesize styleBits;
114 @synthesize isEnabled;
115
116 - (void) updateMinMaxSize:(BOOL)resizable {
117 if (resizable) {
118 [self.nsWindow setMinSize:self.javaMinSize];
119 [self.nsWindow setMaxSize:self.javaMaxSize];
120 } else {
121 NSRect currentFrame = [self.nsWindow frame];
122 [self.nsWindow setMinSize:currentFrame.size];
123 [self.nsWindow setMaxSize:currentFrame.size];
124 }
125 }
126
127 // creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits
128 + (NSUInteger) styleMaskForStyleBits:(jint)styleBits {
129 NSUInteger type = 0;
130 if (IS(styleBits, DECORATED)) {
131 type |= NSTitledWindowMask;
132 if (IS(styleBits, CLOSEABLE)) type |= NSClosableWindowMask;
133 if (IS(styleBits, MINIMIZABLE)) type |= NSMiniaturizableWindowMask;
134 if (IS(styleBits, RESIZABLE)) type |= NSResizableWindowMask;
135 } else {
136 type |= NSBorderlessWindowMask;
137 }
138
139 if (IS(styleBits, TEXTURED)) type |= NSTexturedBackgroundWindowMask;
140 if (IS(styleBits, UNIFIED)) type |= NSUnifiedTitleAndToolbarWindowMask;
141 if (IS(styleBits, UTILITY)) type |= NSUtilityWindowMask;
142 if (IS(styleBits, HUD)) type |= NSHUDWindowMask;
143 if (IS(styleBits, SHEET)) type |= NSDocModalWindowMask;
144 if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;
145
146 return type;
147 }
148
149 // updates _METHOD_PROP_BITMASK based properties on the window
150 - (void) setPropertiesForStyleBits:(jint)bits mask:(jint)mask {
151 if (IS(mask, RESIZABLE)) {
152 BOOL resizable = IS(bits, RESIZABLE);
153 [self updateMinMaxSize:resizable];
154 [self.nsWindow setShowsResizeIndicator:resizable];
155 }
156
157 if (IS(mask, HAS_SHADOW)) {
158 [self.nsWindow setHasShadow:IS(bits, HAS_SHADOW)];
159 }
160
161 if (IS(mask, ZOOMABLE)) {
162 [[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:IS(bits, ZOOMABLE)];
163 }
164
165 if (IS(mask, ALWAYS_ON_TOP)) {
166 [self.nsWindow setLevel:IS(bits, ALWAYS_ON_TOP) ? NSFloatingWindowLevel : NSNormalWindowLevel];
167 }
168
169 if (IS(mask, HIDES_ON_DEACTIVATE)) {
170 [self.nsWindow setHidesOnDeactivate:IS(bits, HIDES_ON_DEACTIVATE)];
171 }
172
173 if (IS(mask, DRAGGABLE_BACKGROUND)) {
174 [self.nsWindow setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];
175 }
176
177 if (IS(mask, DOCUMENT_MODIFIED)) {
178 [self.nsWindow setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
179 }
180
181 if ([self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {
182 if (IS(mask, FULLSCREENABLE)) {
183 [self.nsWindow setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
184 } else {
185 [self.nsWindow setCollectionBehavior:NSWindowCollectionBehaviorDefault];
186 }
187 }
188
189 }
190
191 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
192 styleBits:(jint)bits
193 frameRect:(NSRect)rect
194 contentView:(NSView *)view
195 {
196 AWT_ASSERT_APPKIT_THREAD;
197
198 NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
199 NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
200 if (contentRect.size.width <= 0.0) {
201 contentRect.size.width = 1.0;
202 }
203 if (contentRect.size.height <= 0.0) {
204 contentRect.size.height = 1.0;
205 }
206
207 self = [super init];
208
209 if (self == nil) return nil; // no hope
210
211 if (IS(bits, UTILITY) ||
212 IS(bits, NONACTIVATING) ||
213 IS(bits, HUD) ||
214 IS(bits, HIDES_ON_DEACTIVATE))
215 {
216 self.nsWindow = [[AWTWindow_Panel alloc] initWithDelegate:self
217 frameRect:contentRect
218 styleMask:styleMask
219 contentView:view];
220 }
221 else
222 {
223 // These windows will appear in the window list in the dock icon menu
224 self.nsWindow = [[AWTWindow_Normal alloc] initWithDelegate:self
225 frameRect:contentRect
226 styleMask:styleMask
227 contentView:view];
228 }
229
230 if (self.nsWindow == nil) return nil; // no hope either
231
232 self.isEnabled = YES;
233 self.javaPlatformWindow = platformWindow;
234 self.styleBits = bits;
235 [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
236
237 return self;
238 }
239
240 // checks that this window is under the mouse cursor and this point is not overlapped by others windows
241 - (BOOL) isTopmostWindowUnderMouse {
242
243 int currentWinID = [self.nsWindow windowNumber];
244
245 NSRect screenRect = [[NSScreen mainScreen] frame];
246 NSPoint nsMouseLocation = [NSEvent mouseLocation];
247 CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
248
249 NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
250
251
252 for (NSDictionary *window in windows) {
253 int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
254 if (layer == 0) {
255 int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
256 CGRect rect;
257 CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
258 if (CGRectContainsPoint(rect, cgMouseLocation)) {
259 return currentWinID == winID;
260 } else if (currentWinID == winID) {
261 return NO;
262 }
263 }
264 }
265 return NO;
266 }
267
268 - (void) synthesizeMouseEnteredExitedEvents {
269
270 int eventType = 0;
271 BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
272 BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
273
274 if (isUnderMouse && !mouseIsOver) {
275 eventType = NSMouseEntered;
276 } else if (!isUnderMouse && mouseIsOver) {
277 eventType = NSMouseExited;
278 } else {
279 return;
280 }
281
282 NSPoint screenLocation = [NSEvent mouseLocation];
283 NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
284 int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
285
286 NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
287 location: windowLocation
288 modifierFlags: modifierFlags
289 timestamp: 0
290 windowNumber: [self.nsWindow windowNumber]
291 context: nil
292 eventNumber: 0
293 trackingNumber: 0
294 userData: nil
295 ];
296
297 [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
298 }
299
300 - (void) dealloc {
301 AWT_ASSERT_APPKIT_THREAD;
302
303 JNIEnv *env = [ThreadUtilities getJNIEnv];
304 [self.javaPlatformWindow setJObject:nil withEnv:env];
305
306 self.nsWindow = nil;
307
308 [super dealloc];
309 }
310
311 // NSWindow overrides
312 - (BOOL) canBecomeKeyWindow {
313 AWT_ASSERT_APPKIT_THREAD;
314 return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_KEY);
315 }
316
317 - (BOOL) canBecomeMainWindow {
318 AWT_ASSERT_APPKIT_THREAD;
319 return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);
320 }
321
322 - (BOOL) worksWhenModal {
323 AWT_ASSERT_APPKIT_THREAD;
324 return IS(self.styleBits, MODAL_EXCLUDED);
325 }
326
327
328 // Gesture support
329 - (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {
330 AWT_ASSERT_APPKIT_THREAD;
331
332 JNIEnv *env = [ThreadUtilities getJNIEnv];
333 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
334 if (platformWindow != NULL) {
335 // extract the target AWT Window object out of the CPlatformWindow
336 static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
337 jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
338 if (awtWindow != NULL) {
339 // translate the point into Java coordinates
340 NSPoint loc = [event locationInWindow];
341 loc.y = [self.nsWindow frame].size.height - loc.y;
342
343 // send up to the GestureHandler to recursively dispatch on the AWT event thread
344 static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");
345 static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");
346 JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
347 (*env)->DeleteLocalRef(env, awtWindow);
348 }
349 (*env)->DeleteLocalRef(env, platformWindow);
350 }
351 }
352
353 - (void)beginGestureWithEvent:(NSEvent *)event {
354 [self postGesture:event
355 as:com_apple_eawt_event_GestureHandler_PHASE
356 a:-1.0
357 b:0.0];
358 }
359
360 - (void)endGestureWithEvent:(NSEvent *)event {
361 [self postGesture:event
362 as:com_apple_eawt_event_GestureHandler_PHASE
363 a:1.0
364 b:0.0];
365 }
366
367 - (void)magnifyWithEvent:(NSEvent *)event {
368 [self postGesture:event
369 as:com_apple_eawt_event_GestureHandler_MAGNIFY
370 a:[event magnification]
371 b:0.0];
372 }
373
374 - (void)rotateWithEvent:(NSEvent *)event {
375 [self postGesture:event
376 as:com_apple_eawt_event_GestureHandler_ROTATE
377 a:[event rotation]
378 b:0.0];
379 }
380
381 - (void)swipeWithEvent:(NSEvent *)event {
382 [self postGesture:event
383 as:com_apple_eawt_event_GestureHandler_SWIPE
384 a:[event deltaX]
385 b:[event deltaY]];
386 }
387
388
389 // NSWindowDelegate methods
390
391 - (void) _deliverMoveResizeEvent {
392 AWT_ASSERT_APPKIT_THREAD;
393
394 // deliver the event if this is a user-initiated live resize or as a side-effect
395 // of a Java initiated resize, because AppKit can override the bounds and force
396 // the bounds of the window to avoid the Dock or remain on screen.
397 [AWTToolkit eventCountPlusPlus];
398 JNIEnv *env = [ThreadUtilities getJNIEnv];
399 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
400 if (platformWindow == NULL) {
401 // TODO: create generic AWT assert
402 }
403
404 NSRect frame = ConvertNSScreenRect(env, [self.nsWindow frame]);
405
406 static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIII)V");
407 JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,
408 (jint)frame.origin.x,
409 (jint)frame.origin.y,
410 (jint)frame.size.width,
411 (jint)frame.size.height);
412 (*env)->DeleteLocalRef(env, platformWindow);
413 }
414
415 - (void)windowDidMove:(NSNotification *)notification {
416 AWT_ASSERT_APPKIT_THREAD;
417
418 [self _deliverMoveResizeEvent];
419 }
420
421 - (void)windowDidResize:(NSNotification *)notification {
422 AWT_ASSERT_APPKIT_THREAD;
423
424 [self _deliverMoveResizeEvent];
425 }
426
427 - (void)windowDidExpose:(NSNotification *)notification {
428 AWT_ASSERT_APPKIT_THREAD;
429
430 [AWTToolkit eventCountPlusPlus];
431 // TODO: don't see this callback invoked anytime so we track
432 // window exposing in _setVisible:(BOOL)
433 }
434
435 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)proposedFrame {
436 AWT_ASSERT_APPKIT_THREAD;
437
438 [AWTToolkit eventCountPlusPlus];
439 JNIEnv *env = [ThreadUtilities getJNIEnv];
440 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
441 if (platformWindow != NULL) {
442 static JNF_MEMBER_CACHE(jm_deliverZoom, jc_CPlatformWindow, "deliverZoom", "(Z)V");
443 JNFCallVoidMethod(env, platformWindow, jm_deliverZoom, ![window isZoomed]);
444 (*env)->DeleteLocalRef(env, platformWindow);
445 }
446 return YES;
447 }
448
449 - (void) _deliverIconify:(BOOL)iconify {
450 AWT_ASSERT_APPKIT_THREAD;
451
452 [AWTToolkit eventCountPlusPlus];
453 JNIEnv *env = [ThreadUtilities getJNIEnv];
454 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
455 if (platformWindow != NULL) {
456 static JNF_MEMBER_CACHE(jm_deliverIconify, jc_CPlatformWindow, "deliverIconify", "(Z)V");
457 JNFCallVoidMethod(env, platformWindow, jm_deliverIconify, iconify);
458 (*env)->DeleteLocalRef(env, platformWindow);
459 }
460 }
461
462 - (void)windowDidMiniaturize:(NSNotification *)notification {
463 AWT_ASSERT_APPKIT_THREAD;
464
465 [self _deliverIconify:JNI_TRUE];
466 }
467
468 - (void)windowDidDeminiaturize:(NSNotification *)notification {
469 AWT_ASSERT_APPKIT_THREAD;
470
471 [self _deliverIconify:JNI_FALSE];
472 }
473
474 - (void) _deliverWindowFocusEvent:(BOOL)focused {
475 //AWT_ASSERT_APPKIT_THREAD;
476
477 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
478 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
479 if (platformWindow != NULL) {
480 static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(Z)V");
481 JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused);
482 (*env)->DeleteLocalRef(env, platformWindow);
483 }
484 }
485
486
487 - (void) windowDidBecomeKey: (NSNotification *) notification {
488 AWT_ASSERT_APPKIT_THREAD;
489 [AWTToolkit eventCountPlusPlus];
490 [CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
491 [self _deliverWindowFocusEvent:YES];
492 }
493
494 - (void) windowDidResignKey: (NSNotification *) notification {
495 // TODO: check why sometimes at start is invoked *not* on AppKit main thread.
496 AWT_ASSERT_APPKIT_THREAD;
497 [AWTToolkit eventCountPlusPlus];
498 [self.javaMenuBar deactivate];
499 [self _deliverWindowFocusEvent:NO];
500 }
501
502 - (void) windowDidBecomeMain: (NSNotification *) notification {
503 AWT_ASSERT_APPKIT_THREAD;
504 [AWTToolkit eventCountPlusPlus];
505
506 JNIEnv *env = [ThreadUtilities getJNIEnv];
507 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
508 if (platformWindow != NULL) {
509 static JNF_MEMBER_CACHE(jm_windowDidBecomeMain, jc_CPlatformWindow, "windowDidBecomeMain", "()V");
510 JNFCallVoidMethod(env, platformWindow, jm_windowDidBecomeMain);
511 (*env)->DeleteLocalRef(env, platformWindow);
512 }
513 }
514
515 - (BOOL)windowShouldClose:(id)sender {
516 AWT_ASSERT_APPKIT_THREAD;
517 [AWTToolkit eventCountPlusPlus];
518 JNIEnv *env = [ThreadUtilities getJNIEnv];
519 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
520 if (platformWindow != NULL) {
521 static JNF_MEMBER_CACHE(jm_deliverWindowClosingEvent, jc_CPlatformWindow, "deliverWindowClosingEvent", "()V");
522 JNFCallVoidMethod(env, platformWindow, jm_deliverWindowClosingEvent);
523 (*env)->DeleteLocalRef(env, platformWindow);
524 }
525 // The window will be closed (if allowed) as result of sending Java event
526 return NO;
527 }
528
529
530 - (void)_notifyFullScreenOp:(jint)op withEnv:(JNIEnv *)env {
531 static JNF_CLASS_CACHE(jc_FullScreenHandler, "com/apple/eawt/FullScreenHandler");
532 static JNF_STATIC_MEMBER_CACHE(jm_notifyFullScreenOperation, jc_FullScreenHandler, "handleFullScreenEventFromNative", "(Ljava/awt/Window;I)V");
533 static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
534 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
535 if (platformWindow != NULL) {
536 jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
537 if (awtWindow != NULL) {
538 JNFCallStaticVoidMethod(env, jm_notifyFullScreenOperation, awtWindow, op);
539 (*env)->DeleteLocalRef(env, awtWindow);
540 }
541 (*env)->DeleteLocalRef(env, platformWindow);
542 }
543 }
544
545
546 - (void)windowWillEnterFullScreen:(NSNotification *)notification {
547 static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
548 JNIEnv *env = [ThreadUtilities getJNIEnv];
549 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
550 if (platformWindow != NULL) {
551 JNFCallVoidMethod(env, platformWindow, jm_windowWillEnterFullScreen);
552 [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_ENTER withEnv:env];
553 (*env)->DeleteLocalRef(env, platformWindow);
554 }
555 }
556
557 - (void)windowDidEnterFullScreen:(NSNotification *)notification {
558 static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");
559 JNIEnv *env = [ThreadUtilities getJNIEnv];
560 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
561 if (platformWindow != NULL) {
562 JNFCallVoidMethod(env, platformWindow, jm_windowDidEnterFullScreen);
563 [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_ENTER withEnv:env];
564 (*env)->DeleteLocalRef(env, platformWindow);
565 }
566 }
567
568 - (void)windowWillExitFullScreen:(NSNotification *)notification {
569 static JNF_MEMBER_CACHE(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");
570 JNIEnv *env = [ThreadUtilities getJNIEnv];
571 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
572 if (platformWindow != NULL) {
573 JNFCallVoidMethod(env, platformWindow, jm_windowWillExitFullScreen);
574 [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_EXIT withEnv:env];
575 (*env)->DeleteLocalRef(env, platformWindow);
576 }
577 }
578
579 - (void)windowDidExitFullScreen:(NSNotification *)notification {
580 static JNF_MEMBER_CACHE(jm_windowDidExitFullScreen, jc_CPlatformWindow, "windowDidExitFullScreen", "()V");
581 JNIEnv *env = [ThreadUtilities getJNIEnv];
582 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
583 if (platformWindow != NULL) {
584 JNFCallVoidMethod(env, platformWindow, jm_windowDidExitFullScreen);
585 [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_EXIT withEnv:env];
586 (*env)->DeleteLocalRef(env, platformWindow);
587 }
588 }
589
590 - (void)sendEvent:(NSEvent *)event {
591 if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
592
593 NSPoint p = [NSEvent mouseLocation];
594 NSRect frame = [self.nsWindow frame];
595 NSRect contentRect = [self.nsWindow contentRectForFrameRect:frame];
596
597 // Check if the click happened in the non-client area (title bar)
598 if (p.y >= (frame.origin.y + contentRect.size.height)) {
599 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
600 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
601 // Currently, no need to deliver the whole NSEvent.
602 static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
603 JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
604 }
605 }
606 }
607
608 - (void)constrainSize:(NSSize*)size {
609 float minWidth = 0.f, minHeight = 0.f;
610
611 if (IS(self.styleBits, DECORATED)) {
612 NSRect frame = [self.nsWindow frame];
613 NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self.nsWindow styleMask]];
614
615 float top = frame.size.height - contentRect.size.height;
616 float left = contentRect.origin.x - frame.origin.x;
617 float bottom = contentRect.origin.y - frame.origin.y;
618 float right = frame.size.width - (contentRect.size.width + left);
619
620 // Speculative estimation: 80 - enough for window decorations controls
621 minWidth += left + right + 80;
622 minHeight += top + bottom;
623 }
624
625 minWidth = MAX(1.f, minWidth);
626 minHeight = MAX(1.f, minHeight);
627
628 size->width = MAX(size->width, minWidth);
629 size->height = MAX(size->height, minHeight);
630 }
631
632 - (void) setEnabled: (BOOL)flag {
633 self.isEnabled = flag;
634
635 if (IS(self.styleBits, CLOSEABLE)) {
636 [[self.nsWindow standardWindowButton:NSWindowCloseButton] setEnabled: flag];
637 }
638
639 if (IS(self.styleBits, MINIMIZABLE)) {
640 [[self.nsWindow standardWindowButton:NSWindowMiniaturizeButton] setEnabled: flag];
641 }
642
643 if (IS(self.styleBits, ZOOMABLE)) {
644 [[self.nsWindow standardWindowButton:NSWindowZoomButton] setEnabled: flag];
645 }
646
647 if (IS(self.styleBits, RESIZABLE)) {
648 [self updateMinMaxSize:flag];
649 [self.nsWindow setShowsResizeIndicator:flag];
650 }
651 }
652
653 @end // AWTWindow
654
655
656 /*
657 * Class: sun_lwawt_macosx_CPlatformWindow
658 * Method: nativeCreateNSWindow
659 * Signature: (JJIIII)J
660 */
661 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
662 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
663 {
664 __block AWTWindow *window = nil;
665
666 JNF_COCOA_ENTER(env);
667 AWT_ASSERT_NOT_APPKIT_THREAD;
668
669 JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
670 NSView *contentView = OBJC(contentViewPtr);
671 NSRect frameRect = NSMakeRect(x, y, w, h);
672
673 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
674 AWT_ASSERT_APPKIT_THREAD;
675
676 window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow
677 styleBits:styleBits
678 frameRect:frameRect
679 contentView:contentView];
680
681 if (window) CFRetain(window);
682 [window release]; // GC
683 }];
684
685 JNF_COCOA_EXIT(env);
686
687 return ptr_to_jlong(window ? window.nsWindow : nil);
688 }
689
690 /*
691 * Class: sun_lwawt_macosx_CPlatformWindow
692 * Method: nativeSetNSWindowStyleBits
693 * Signature: (JII)V
694 */
695 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowStyleBits
696 (JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)
697 {
698 JNF_COCOA_ENTER(env);
699 AWT_ASSERT_NOT_APPKIT_THREAD;
700
701 NSWindow *nsWindow = OBJC(windowPtr);
702 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
703 AWT_ASSERT_APPKIT_THREAD;
704
705 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
706
707 // scans the bit field, and only updates the values requested by the mask
708 // (this implicity handles the _CALLBACK_PROP_BITMASK case, since those are passive reads)
709 jint newBits = window.styleBits & ~mask | bits & mask;
710
711 // resets the NSWindow's style mask if the mask intersects any of those bits
712 if (mask & MASK(_STYLE_PROP_BITMASK)) {
713 [nsWindow setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];
714 }
715
716 // calls methods on NSWindow to change other properties, based on the mask
717 if (mask & MASK(_METHOD_PROP_BITMASK)) {
718 [window setPropertiesForStyleBits:bits mask:mask];
719 }
720
721 window.styleBits = newBits;
722 }];
723
724 JNF_COCOA_EXIT(env);
725 }
726
727 /*
728 * Class: sun_lwawt_macosx_CPlatformWindow
729 * Method: nativeSetNSWindowMenuBar
730 * Signature: (JJ)V
731 */
732 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMenuBar
733 (JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)
734 {
735 JNF_COCOA_ENTER(env);
736 AWT_ASSERT_NOT_APPKIT_THREAD;
737
738 NSWindow *nsWindow = OBJC(windowPtr);
739 CMenuBar *menuBar = OBJC(menuBarPtr);
740 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
741 AWT_ASSERT_APPKIT_THREAD;
742
743 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
744
745 if ([nsWindow isKeyWindow]) [window.javaMenuBar deactivate];
746 window.javaMenuBar = menuBar;
747
748 // if ([self isKeyWindow]) {
749 [CMenuBar activate:window.javaMenuBar modallyDisabled:NO];
750 // }
751 }];
752
753 JNF_COCOA_EXIT(env);
754 }
755
756 /*
757 * Class: sun_lwawt_macosx_CPlatformWindow
758 * Method: nativeGetNSWindowInsets
759 * Signature: (J)Ljava/awt/Insets;
760 */
761 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowInsets
762 (JNIEnv *env, jclass clazz, jlong windowPtr)
763 {
764 jobject ret = NULL;
765
766 JNF_COCOA_ENTER(env);
767 AWT_ASSERT_NOT_APPKIT_THREAD;
768
769 NSWindow *nsWindow = OBJC(windowPtr);
770 __block NSRect contentRect = NSZeroRect;
771 __block NSRect frame = NSZeroRect;
772
773 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
774 AWT_ASSERT_APPKIT_THREAD;
775
776 frame = [nsWindow frame];
777 contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[nsWindow styleMask]];
778 }];
779
780 jint top = (jint)(frame.size.height - contentRect.size.height);
781 jint left = (jint)(contentRect.origin.x - frame.origin.x);
782 jint bottom = (jint)(contentRect.origin.y - frame.origin.y);
783 jint right = (jint)(frame.size.width - (contentRect.size.width + left));
784
785 static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
786 static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
787 ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);
788
789 JNF_COCOA_EXIT(env);
790 return ret;
791 }
792
793 /*
794 * Class: sun_lwawt_macosx_CPlatformWindow
795 * Method: nativeSetNSWindowBounds
796 * Signature: (JDDDD)V
797 */
798 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
799 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
800 {
801 JNF_COCOA_ENTER(env);
802 AWT_ASSERT_NOT_APPKIT_THREAD;
803
804 NSRect jrect = NSMakeRect(originX, originY, width, height);
805
806 // TODO: not sure we need displayIfNeeded message in our view
807 NSWindow *nsWindow = OBJC(windowPtr);
808 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
809 AWT_ASSERT_APPKIT_THREAD;
810
811 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
812
813 NSRect rect = ConvertNSScreenRect(NULL, jrect);
814 [window constrainSize:&rect.size];
815
816 [nsWindow setFrame:rect display:YES];
817
818 // only start tracking events if pointer is above the toplevel
819 // TODO: should post an Entered event if YES.
820 NSPoint mLocation = [NSEvent mouseLocation];
821 [nsWindow setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
822
823 // ensure we repaint the whole window after the resize operation
824 // (this will also re-enable screen updates, which were disabled above)
825 // TODO: send PaintEvent
826
827 [window synthesizeMouseEnteredExitedEvents];
828 }];
829
830 JNF_COCOA_EXIT(env);
831 }
832
833 /*
834 * Class: sun_lwawt_macosx_CPlatformWindow
835 * Method: nativeSetNSWindowMinMax
836 * Signature: (JDDDD)V
837 */
838 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
839 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
840 {
841 JNF_COCOA_ENTER(env);
842 AWT_ASSERT_NOT_APPKIT_THREAD;
843
844 if (minW < 1) minW = 1;
845 if (minH < 1) minH = 1;
846 if (maxW < 1) maxW = 1;
847 if (maxH < 1) maxH = 1;
848
849 NSWindow *nsWindow = OBJC(windowPtr);
850 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
851 AWT_ASSERT_APPKIT_THREAD;
852
853 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
854
855 NSSize min = { minW, minH };
856 NSSize max = { maxW, maxH };
857
858 [window constrainSize:&min];
859 [window constrainSize:&max];
860
861 window.javaMinSize = min;
862 window.javaMaxSize = max;
863 [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
864 }];
865
866 JNF_COCOA_EXIT(env);
867 }
868
869 /*
870 * Class: sun_lwawt_macosx_CPlatformWindow
871 * Method: nativePushNSWindowToBack
872 * Signature: (J)V
873 */
874 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
875 (JNIEnv *env, jclass clazz, jlong windowPtr)
876 {
877 JNF_COCOA_ENTER(env);
878 AWT_ASSERT_NOT_APPKIT_THREAD;
879
880 NSWindow *nsWindow = OBJC(windowPtr);
881 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
882 AWT_ASSERT_APPKIT_THREAD;
883
884 [nsWindow orderBack:nil];
885 }];
886
887 JNF_COCOA_EXIT(env);
888 }
889
890 /*
891 * Class: sun_lwawt_macosx_CPlatformWindow
892 * Method: nativePushNSWindowToFront
893 * Signature: (J)V
894 */
895 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront
896 (JNIEnv *env, jclass clazz, jlong windowPtr)
897 {
898 JNF_COCOA_ENTER(env);
899 AWT_ASSERT_NOT_APPKIT_THREAD;
900
901 NSWindow *nsWindow = OBJC(windowPtr);
902 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
903 AWT_ASSERT_APPKIT_THREAD;
904
905 if (![nsWindow isKeyWindow]) {
906 [nsWindow makeKeyAndOrderFront:nsWindow];
907 } else {
908 [nsWindow orderFront:nsWindow];
909 }
910 }];
911
912 JNF_COCOA_EXIT(env);
913 }
914
915 /*
916 * Class: sun_lwawt_macosx_CPlatformWindow
917 * Method: nativeSetNSWindowTitle
918 * Signature: (JLjava/lang/String;)V
919 */
920 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTitle
921 (JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)
922 {
923 JNF_COCOA_ENTER(env);
924 AWT_ASSERT_NOT_APPKIT_THREAD;
925
926 NSWindow *nsWindow = OBJC(windowPtr);
927 [nsWindow performSelectorOnMainThread:@selector(setTitle:)
928 withObject:JNFJavaToNSString(env, jtitle)
929 waitUntilDone:NO];
930
931 JNF_COCOA_EXIT(env);
932 }
933
934 /*
935 * Class: sun_lwawt_macosx_CPlatformWindow
936 * Method: nativeRevalidateNSWindowShadow
937 * Signature: (J)V
938 */
939 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow
940 (JNIEnv *env, jclass clazz, jlong windowPtr)
941 {
942 JNF_COCOA_ENTER(env);
943 AWT_ASSERT_NOT_APPKIT_THREAD;
944
945 NSWindow *nsWindow = OBJC(windowPtr);
946 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
947 AWT_ASSERT_APPKIT_THREAD;
948
949 [nsWindow invalidateShadow];
950 }];
951
952 JNF_COCOA_EXIT(env);
953 }
954
955 /*
956 * Class: sun_lwawt_macosx_CPlatformWindow
957 * Method: nativeScreenOn_AppKitThread
958 * Signature: (J)I
959 */
960 JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeScreenOn_1AppKitThread
961 (JNIEnv *env, jclass clazz, jlong windowPtr)
962 {
963 jint ret = 0;
964
965 JNF_COCOA_ENTER(env);
966 AWT_ASSERT_APPKIT_THREAD;
967
968 NSWindow *nsWindow = OBJC(windowPtr);
969 NSDictionary *props = [[nsWindow screen] deviceDescription];
970 ret = [[props objectForKey:@"NSScreenNumber"] intValue];
971
972 JNF_COCOA_EXIT(env);
973
974 return ret;
975 }
976
977 /*
978 * Class: sun_lwawt_macosx_CPlatformWindow
979 * Method: nativeSetNSWindowMinimizedIcon
980 * Signature: (JJ)V
981 */
982 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinimizedIcon
983 (JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)
984 {
985 JNF_COCOA_ENTER(env);
986 AWT_ASSERT_NOT_APPKIT_THREAD;
987
988 NSWindow *nsWindow = OBJC(windowPtr);
989 NSImage *image = OBJC(nsImagePtr);
990 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
991 AWT_ASSERT_APPKIT_THREAD;
992
993 [nsWindow setMiniwindowImage:image];
994 }];
995
996 JNF_COCOA_EXIT(env);
997 }
998
999 /*
1000 * Class: sun_lwawt_macosx_CPlatformWindow
1001 * Method: nativeSetNSWindowRepresentedFilename
1002 * Signature: (JLjava/lang/String;)V
1003 */
1004 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRepresentedFilename
1005 (JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)
1006 {
1007 JNF_COCOA_ENTER(env);
1008 AWT_ASSERT_NOT_APPKIT_THREAD;
1009
1010 NSWindow *nsWindow = OBJC(windowPtr);
1011 NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];
1012 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1013 AWT_ASSERT_APPKIT_THREAD;
1014
1015 [nsWindow setRepresentedURL:url];
1016 }];
1017
1018 JNF_COCOA_EXIT(env);
1019 }
1020
1021 /*
1022 * Class: sun_lwawt_macosx_CPlatformWindow
1023 * Method: nativeSetNSWindowSecurityWarningPositioning
1024 * Signature: (JDDFF)V
1025 */
1026 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
1027 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
1028 {
1029 JNF_COCOA_ENTER(env);
1030 AWT_ASSERT_NOT_APPKIT_THREAD;
1031
1032 [JNFException raise:env as:kRuntimeException reason:"unimplemented"];
1033
1034 JNF_COCOA_EXIT(env);
1035 }
1036
1037 /*
1038 * Class: sun_lwawt_macosx_CPlatformWindow
1039 * Method: nativeSynthesizeMouseEnteredExitedEvents
1040 * Signature: (J)V
1041 */
1042 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
1043 (JNIEnv *env, jclass clazz, jlong windowPtr)
1044 {
1045 JNF_COCOA_ENTER(env);
1046 AWT_ASSERT_NOT_APPKIT_THREAD;
1047
1048 NSWindow *nsWindow = OBJC(windowPtr);
1049 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1050 AWT_ASSERT_APPKIT_THREAD;
1051
1052 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1053
1054 [window synthesizeMouseEnteredExitedEvents];
1055 }];
1056
1057 JNF_COCOA_EXIT(env);
1058 }
1059
1060 /*
1061 * Class: sun_lwawt_macosx_CPlatformWindow
1062 * Method: nativeGetDisplayID_AppKitThread
1063 * Signature: (J)I
1064 */
1065 JNIEXPORT jint JNICALL
1066 Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID_1AppKitThread
1067 (JNIEnv *env, jclass clazz, jlong windowPtr)
1068 {
1069 jint ret; // CGDirectDisplayID
1070
1071 JNF_COCOA_ENTER(env);
1072 AWT_ASSERT_APPKIT_THREAD;
1073
1074 NSWindow *window = OBJC(windowPtr);
1075 NSScreen *screen = [window screen];
1076 NSDictionary *deviceDescription = [screen deviceDescription];
1077 NSNumber *displayID = [deviceDescription objectForKey:@"NSScreenNumber"];
1078 ret = (jint)[displayID intValue];
1079
1080 JNF_COCOA_EXIT(env);
1081
1082 return ret;
1083 }
1084
1085 /*
1086 * Class: sun_lwawt_macosx_CPlatformWindow
1087 * Method: _toggleFullScreenMode
1088 * Signature: (J)V
1089 */
1090 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow__1toggleFullScreenMode
1091 (JNIEnv *env, jobject peer, jlong windowPtr)
1092 {
1093 JNF_COCOA_ENTER(env);
1094
1095 NSWindow *nsWindow = OBJC(windowPtr);
1096 SEL toggleFullScreenSelector = @selector(toggleFullScreen:);
1097 if (![nsWindow respondsToSelector:toggleFullScreenSelector]) return;
1098
1099 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1100 [nsWindow performSelector:toggleFullScreenSelector withObject:nil];
1101 }];
1102
1103 JNF_COCOA_EXIT(env);
1104 }
1105
1106 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CMouseInfoPeer_nativeIsWindowUnderMouse
1107 (JNIEnv *env, jclass clazz, jlong windowPtr)
1108 {
1109 __block jboolean underMouse = JNI_FALSE;
1110
1111 JNF_COCOA_ENTER(env);
1112 AWT_ASSERT_NOT_APPKIT_THREAD;
1113
1114 NSWindow *nsWindow = OBJC(windowPtr);
1115 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
1116 AWT_ASSERT_APPKIT_THREAD;
1117
1118 NSPoint pt = [nsWindow mouseLocationOutsideOfEventStream];
1119 underMouse = [[nsWindow contentView] hitTest:pt] != nil;
1120 }];
1121
1122 JNF_COCOA_EXIT(env);
1123
1124 return underMouse;
1125 }
1126
1127 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled
1128 (JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)
1129 {
1130 JNF_COCOA_ENTER(env);
1131
1132 NSWindow *nsWindow = OBJC(windowPtr);
1133 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1134 AWTWindow *window = (AWTWindow*)[nsWindow delegate];
1135
1136 [window setEnabled: isEnabled];
1137 }];
1138
1139 JNF_COCOA_EXIT(env);
1140 }
1141
--- EOF ---