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
141
142 if (IS(mask, DOCUMENT_MODIFIED)) {
143 [self setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
144 }
145
146 if ([self respondsToSelector:@selector(toggleFullScreen:)]) {
147 if (IS(mask, FULLSCREENABLE)) {
148 [self setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
149 } else {
150 [self setCollectionBehavior:NSWindowCollectionBehaviorDefault];
151 }
152 }
153
154 }
155
156 - (BOOL) shouldShowGrowBox {
157 return isSnowLeopardOrLower() && IS(self.styleBits, RESIZABLE);
158 }
159
160 - (NSImage *) createGrowBoxImage {
161 NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(12, 12)];
162 JRSUIControlRef growBoxWidget = JRSUIControlCreate(FALSE);
163 JRSUIControlSetWidget(growBoxWidget, kJRSUI_Widget_growBoxTextured);
164 JRSUIControlSetWindowType(growBoxWidget, kJRSUI_WindowType_utility);
165 JRSUIRendererRef renderer = JRSUIRendererCreate();
166 [image lockFocus]; // sets current graphics context to that of the image
167 JRSUIControlDraw(renderer, growBoxWidget, [[NSGraphicsContext currentContext] graphicsPort], CGRectMake(0, 1, 11, 11));
168 [image unlockFocus];
169 JRSUIRendererRelease(renderer);
170 JRSUIControlRelease(growBoxWidget);
171 return image;
172 }
173
174 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
175 styleBits:(jint)bits
176 frameRect:(NSRect)rect
177 contentView:(NSView *)view
178 {
179 AWT_ASSERT_APPKIT_THREAD;
180
181 NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
182 NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
183 if (contentRect.size.width <= 0.0) {
184 contentRect.size.width = 1.0;
185 }
186 if (contentRect.size.height <= 0.0) {
187 contentRect.size.height = 1.0;
530 }
531
532 - (void)sendEvent:(NSEvent *)event {
533 if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
534
535 NSPoint p = [NSEvent mouseLocation];
536 NSRect frame = [self frame];
537 NSRect contentRect = [self contentRectForFrameRect:frame];
538
539 // Check if the click happened in the non-client area (title bar)
540 if (p.y >= (frame.origin.y + contentRect.size.height)) {
541 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
542 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
543 // Currently, no need to deliver the whole NSEvent.
544 static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
545 JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
546 }
547 }
548 [super sendEvent:event];
549 }
550 @end // AWTWindow
551
552
553 /*
554 * Class: sun_lwawt_macosx_CPlatformWindow
555 * Method: nativeCreateNSWindow
556 * Signature: (JJIIII)J
557 */
558 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
559 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
560 {
561 __block AWTWindow *window = nil;
562
563 JNF_COCOA_ENTER(env);
564 AWT_ASSERT_NOT_APPKIT_THREAD;
565
566 JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
567 NSView *contentView = OBJC(contentViewPtr);
568 NSRect frameRect = NSMakeRect(x, y, w, h);
569
685
686 /*
687 * Class: sun_lwawt_macosx_CPlatformWindow
688 * Method: nativeSetNSWindowBounds
689 * Signature: (JDDDD)V
690 */
691 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
692 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
693 {
694 JNF_COCOA_ENTER(env);
695 AWT_ASSERT_NOT_APPKIT_THREAD;
696
697 NSRect jrect = NSMakeRect(originX, originY, width, height);
698
699 // TODO: not sure we need displayIfNeeded message in our view
700 AWTWindow *window = OBJC(windowPtr);
701 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
702 AWT_ASSERT_APPKIT_THREAD;
703
704 NSRect rect = ConvertNSScreenRect(NULL, jrect);
705 [window setFrame:rect display:YES];
706
707 // only start tracking events if pointer is above the toplevel
708 // TODO: should post an Entered event if YES.
709 NSPoint mLocation = [NSEvent mouseLocation];
710 [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
711
712 // ensure we repaint the whole window after the resize operation
713 // (this will also re-enable screen updates, which were disabled above)
714 // TODO: send PaintEvent
715 }];
716
717 JNF_COCOA_EXIT(env);
718 }
719
720 /*
721 * Class: sun_lwawt_macosx_CPlatformWindow
722 * Method: nativeSetNSWindowMinMax
723 * Signature: (JDDDD)V
724 */
725 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
726 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
727 {
728 JNF_COCOA_ENTER(env);
729 AWT_ASSERT_NOT_APPKIT_THREAD;
730
731 if (minW < 1) minW = 1;
732 if (minH < 1) minH = 1;
733 if (maxW < 1) maxW = 1;
734 if (maxH < 1) maxH = 1;
735
736 NSSize min = { minW, minH };
737 NSSize max = { maxW, maxH };
738
739 AWTWindow *window = OBJC(windowPtr);
740 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
741 AWT_ASSERT_APPKIT_THREAD;
742
743 window.javaMinSize = min;
744 window.javaMaxSize = max;
745 [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
746 }];
747
748 JNF_COCOA_EXIT(env);
749 }
750
751 /*
752 * Class: sun_lwawt_macosx_CPlatformWindow
753 * Method: nativePushNSWindowToBack
754 * Signature: (J)V
755 */
756 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
757 (JNIEnv *env, jclass clazz, jlong windowPtr)
758 {
759 JNF_COCOA_ENTER(env);
760 AWT_ASSERT_NOT_APPKIT_THREAD;
761
|
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
141
142 if (IS(mask, DOCUMENT_MODIFIED)) {
143 [self setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
144 }
145
146 if ([self respondsToSelector:@selector(toggleFullScreen:)]) {
147 if (IS(mask, FULLSCREENABLE)) {
148 [self setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
149 } else {
150 [self setCollectionBehavior:NSWindowCollectionBehaviorDefault];
151 }
152 }
153
154 }
155
156 - (BOOL) shouldShowGrowBox {
157 return isSnowLeopardOrLower() && IS(self.styleBits, RESIZABLE);
158 }
159
160 - (NSImage *) createGrowBoxImage {
161 NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(GROW_BOX_SIZE, GROW_BOX_SIZE)];
162 JRSUIControlRef growBoxWidget = JRSUIControlCreate(FALSE);
163 JRSUIControlSetWidget(growBoxWidget, kJRSUI_Widget_growBoxTextured);
164 JRSUIControlSetWindowType(growBoxWidget, kJRSUI_WindowType_utility);
165 JRSUIRendererRef renderer = JRSUIRendererCreate();
166 [image lockFocus]; // sets current graphics context to that of the image
167 JRSUIControlDraw(renderer, growBoxWidget, [[NSGraphicsContext currentContext] graphicsPort], CGRectMake(0, 1, GROW_BOX_SIZE - 1, GROW_BOX_SIZE - 1));
168 [image unlockFocus];
169 JRSUIRendererRelease(renderer);
170 JRSUIControlRelease(growBoxWidget);
171 return image;
172 }
173
174 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
175 styleBits:(jint)bits
176 frameRect:(NSRect)rect
177 contentView:(NSView *)view
178 {
179 AWT_ASSERT_APPKIT_THREAD;
180
181 NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
182 NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
183 if (contentRect.size.width <= 0.0) {
184 contentRect.size.width = 1.0;
185 }
186 if (contentRect.size.height <= 0.0) {
187 contentRect.size.height = 1.0;
530 }
531
532 - (void)sendEvent:(NSEvent *)event {
533 if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
534
535 NSPoint p = [NSEvent mouseLocation];
536 NSRect frame = [self frame];
537 NSRect contentRect = [self contentRectForFrameRect:frame];
538
539 // Check if the click happened in the non-client area (title bar)
540 if (p.y >= (frame.origin.y + contentRect.size.height)) {
541 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
542 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
543 // Currently, no need to deliver the whole NSEvent.
544 static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
545 JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
546 }
547 }
548 [super sendEvent:event];
549 }
550
551 - (void)constrainSize:(NSSize*)size {
552 float minWidth = 0.f, minHeight = 0.f;
553
554 if (IS(self.styleBits, DECORATED)) {
555 NSRect frame = [self frame];
556 NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[self styleMask]];
557
558 float top = frame.size.height - contentRect.size.height;
559 float left = contentRect.origin.x - frame.origin.x;
560 float bottom = contentRect.origin.y - frame.origin.y;
561 float right = frame.size.width - (contentRect.size.width + left);
562
563 // Speculative estimation: 80 - enough for window decorations controls
564 minWidth += left + right + 80;
565 minHeight += top + bottom;
566 }
567
568 if ([self shouldShowGrowBox]) {
569 minWidth = MAX(minWidth, GROW_BOX_SIZE);
570 minHeight += GROW_BOX_SIZE;
571 }
572
573 minWidth = MAX(1.f, minWidth);
574 minHeight = MAX(1.f, minHeight);
575
576 size->width = MAX(size->width, minWidth);
577 size->height = MAX(size->height, minHeight);
578 }
579
580 @end // AWTWindow
581
582
583 /*
584 * Class: sun_lwawt_macosx_CPlatformWindow
585 * Method: nativeCreateNSWindow
586 * Signature: (JJIIII)J
587 */
588 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
589 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
590 {
591 __block AWTWindow *window = nil;
592
593 JNF_COCOA_ENTER(env);
594 AWT_ASSERT_NOT_APPKIT_THREAD;
595
596 JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
597 NSView *contentView = OBJC(contentViewPtr);
598 NSRect frameRect = NSMakeRect(x, y, w, h);
599
715
716 /*
717 * Class: sun_lwawt_macosx_CPlatformWindow
718 * Method: nativeSetNSWindowBounds
719 * Signature: (JDDDD)V
720 */
721 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
722 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
723 {
724 JNF_COCOA_ENTER(env);
725 AWT_ASSERT_NOT_APPKIT_THREAD;
726
727 NSRect jrect = NSMakeRect(originX, originY, width, height);
728
729 // TODO: not sure we need displayIfNeeded message in our view
730 AWTWindow *window = OBJC(windowPtr);
731 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
732 AWT_ASSERT_APPKIT_THREAD;
733
734 NSRect rect = ConvertNSScreenRect(NULL, jrect);
735 [window constrainSize:&rect.size];
736
737 [window setFrame:rect display:YES];
738
739 // only start tracking events if pointer is above the toplevel
740 // TODO: should post an Entered event if YES.
741 NSPoint mLocation = [NSEvent mouseLocation];
742 [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
743
744 // ensure we repaint the whole window after the resize operation
745 // (this will also re-enable screen updates, which were disabled above)
746 // TODO: send PaintEvent
747 }];
748
749 JNF_COCOA_EXIT(env);
750 }
751
752 /*
753 * Class: sun_lwawt_macosx_CPlatformWindow
754 * Method: nativeSetNSWindowMinMax
755 * Signature: (JDDDD)V
756 */
757 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
758 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
759 {
760 JNF_COCOA_ENTER(env);
761 AWT_ASSERT_NOT_APPKIT_THREAD;
762
763 if (minW < 1) minW = 1;
764 if (minH < 1) minH = 1;
765 if (maxW < 1) maxW = 1;
766 if (maxH < 1) maxH = 1;
767
768 AWTWindow *window = OBJC(windowPtr);
769 [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
770 AWT_ASSERT_APPKIT_THREAD;
771
772 NSSize min = { minW, minH };
773 NSSize max = { maxW, maxH };
774
775 [window constrainSize:&min];
776 [window constrainSize:&max];
777
778 window.javaMinSize = min;
779 window.javaMaxSize = max;
780 [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
781 }];
782
783 JNF_COCOA_EXIT(env);
784 }
785
786 /*
787 * Class: sun_lwawt_macosx_CPlatformWindow
788 * Method: nativePushNSWindowToBack
789 * Signature: (J)V
790 */
791 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
792 (JNIEnv *env, jclass clazz, jlong windowPtr)
793 {
794 JNF_COCOA_ENTER(env);
795 AWT_ASSERT_NOT_APPKIT_THREAD;
796
|