1 /* 2 * Copyright (c) 2011, 2017, 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 "common.h" 27 #import "com_sun_glass_events_ViewEvent.h" 28 #import "com_sun_glass_events_WindowEvent.h" 29 #import "com_sun_glass_ui_Window.h" 30 #import "com_sun_glass_ui_Window_Level.h" 31 #import "com_sun_glass_ui_mac_MacWindow.h" 32 33 #import "GlassMacros.h" 34 #import "GlassWindow.h" 35 #import "GlassWindow+Java.h" 36 #import "GlassWindow+Overrides.h" 37 #import "GlassEmbeddedWindow+Overrides.h" 38 #import "GlassView.h" 39 #import "GlassScreen.h" 40 #import "GlassTouches.h" 41 #import "GlassApplication.h" 42 #import "GlassLayer3D.h" 43 #import "GlassHelper.h" 44 45 //#include <stdio.h> 46 //#include <stdarg.h> 47 // 48 //void glass_logf(char *fmt, ...) { 49 // va_list argp; 50 // va_start(argp, fmt); 51 // FILE *f = fopen("/tmp/glass.log", "a"); 52 // vfprintf(f, fmt, argp); 53 // fclose(f); 54 //} 55 // 56 //void Sys_out_sprintf(JNIEnv *env, char *fmt, ...) { 57 // va_list argp; 58 // va_start(argp, fmt); 59 // char buffer[4096]; 60 // vsprintf(buffer, fmt, argp); 61 //// glass_logf("str = %s", buffer); 62 //// return; 63 // jclass sysClass = (*env)->FindClass(env, "java/lang/System"); 64 // if (!sysClass) { glass_logf("Null finding System class\n"); return; } 65 // jclass psClass = (*env)->FindClass(env, "java/io/PrintStream"); 66 // if (!psClass) { glass_logf("Null finding PrintStream class\n"); return; } 67 // jfieldID outField = (*env)->GetStaticFieldID(env, sysClass, "out", "Ljava/io/PrintStream;"); 68 // if (!outField) { glass_logf("Null finding System.out field\n"); return; } 69 // jmethodID printMethod = (*env)->GetMethodID(env, psClass, "print", "(Ljava/lang/String;)V"); 70 // if (!printMethod) { glass_logf("Null finding print method\n"); return; } 71 // jobject outStream = (*env)->GetStaticObjectField(env, sysClass, outField); 72 // if (!outStream) { glass_logf("Null getting System.out object\n"); return; } 73 // jstring theString = (*env)->NewStringUTF(env, buffer); 74 // if (!theString) { glass_logf("Null creating String object\n"); return; } 75 // (*env)->CallVoidMethod(env, outStream, printMethod, theString); 76 // (*env)->DeleteLocalRef(env, theString); 77 //} 78 79 //#define VERBOSE 80 #ifndef VERBOSE 81 #define LOG(MSG, ...) 82 #else 83 #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__); 84 #endif 85 86 #define BROWSER_PARENT_ID -1L 87 88 #pragma mark --- Internal utilities 89 90 static inline GlassWindow *getGlassWindow(JNIEnv *env, jlong jPtr) 91 { 92 assert(jPtr != 0L); 93 94 NSWindow * nsWindow = (NSWindow*)jlong_to_ptr(jPtr); 95 return (GlassWindow*)[nsWindow delegate]; 96 } 97 98 static inline NSView<GlassView> *getMacView(JNIEnv *env, jobject jview) 99 { 100 if (jview != NULL) 101 { 102 jfieldID jfID = (*env)->GetFieldID(env, jViewClass, "ptr", "J"); 103 GLASS_CHECK_EXCEPTION(env); 104 return (NSView<GlassView>*)jlong_to_ptr((*env)->GetLongField(env, jview, jfID)); 105 } 106 else 107 { 108 return nil; 109 } 110 } 111 112 // -------------------------------------------------------------------------------------- 113 // NSWindow/NSPanel descendants implementation 114 #define GLASS_NS_WINDOW_IMPLEMENTATION \ 115 - (id)initWithDelegate:(GlassWindow*)delegate \ 116 frameRect:(NSRect)rect \ 117 styleMask:(NSUInteger)styleMask \ 118 screen:(NSScreen*)screen \ 119 { \ 120 self->gWindow = delegate; /* must be done before calling [super init...] */ \ 121 self = [super initWithContentRect:rect \ 122 styleMask:styleMask \ 123 backing:NSBackingStoreBuffered \ 124 defer:NO \ 125 screen:screen]; \ 126 \ 127 if (self == nil) { \ 128 return nil; \ 129 } \ 130 \ 131 [self setDelegate:delegate]; \ 132 [self setAcceptsMouseMovedEvents:NO]; \ 133 [self setShowsResizeIndicator:NO]; \ 134 [self setAllowsConcurrentViewDrawing:YES]; \ 135 \ 136 [self setReleasedWhenClosed:YES]; \ 137 \ 138 return self; \ 139 } \ 140 \ 141 - (void)dealloc \ 142 { \ 143 id window = self->gWindow; \ 144 LOG("dealloc window: %p", window); \ 145 [super dealloc]; \ 146 [window release]; \ 147 } \ 148 \ 149 - (void)close \ 150 { \ 151 self->gWindow->isClosed = YES; \ 152 [self->gWindow close]; \ 153 LOG("gWindow close: %p", self->gWindow); \ 154 [super close]; \ 155 LOG("super close"); \ 156 } \ 157 /* super calls NSWindow on the next run-loop pass when NSWindow could be released */ \ 158 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent \ 159 { \ 160 [self retain]; \ 161 BOOL result = [super performKeyEquivalent:theEvent]; \ 162 result = result || self->gWindow->isClosed; \ 163 [self release]; \ 164 return result; \ 165 } \ 166 - (BOOL)canBecomeMainWindow \ 167 { \ 168 return [self->gWindow canBecomeMainWindow]; \ 169 } \ 170 - (BOOL)canBecomeKeyWindow \ 171 { \ 172 return [self->gWindow canBecomeKeyWindow]; \ 173 } \ 174 - (void)setHidesOnDeactivate:(BOOL)hideOnDeactivate \ 175 { \ 176 [super setHidesOnDeactivate:NO]; \ 177 } \ 178 - (BOOL)hidesOnDeactivate \ 179 { \ 180 return [self->gWindow hidesOnDeactivate]; \ 181 } \ 182 - (BOOL)worksWhenModal \ 183 { \ 184 return [self->gWindow worksWhenModal]; \ 185 } \ 186 - (void)setBackgroundColor:(NSColor *)color \ 187 { \ 188 [super setBackgroundColor:[self->gWindow setBackgroundColor:color]]; \ 189 } \ 190 - (NSButton *)standardWindowButton:(NSWindowButton)type \ 191 { \ 192 NSButton* button = [super standardWindowButton:type]; \ 193 switch (type) \ 194 { \ 195 case NSWindowDocumentIconButton: \ 196 [button setAcceptsTouchEvents:NO]; \ 197 [button setAction:nil]; \ 198 [button setEnabled:NO]; \ 199 break; \ 200 } \ 201 return button; \ 202 } \ 203 - (void)sendEvent:(NSEvent *)event \ 204 { \ 205 /* Local copy of the id keeps the retain/release calls balanced. */ \ 206 id view = [self->gWindow->view retain]; \ 207 [self->gWindow sendEvent:event]; \ 208 [super sendEvent:event]; \ 209 [view release]; \ 210 } 211 212 @implementation GlassWindow_Normal 213 GLASS_NS_WINDOW_IMPLEMENTATION 214 @end 215 216 @implementation GlassWindow_Panel 217 GLASS_NS_WINDOW_IMPLEMENTATION 218 219 - (void)setWorksWhenModal:(BOOL)worksWhenModal 220 { 221 [super setWorksWhenModal:NO]; 222 } 223 224 - (BOOL)accessibilityIsIgnored 225 { 226 /* In JavaFX NSPanels are used to implement PopupWindows, 227 * which are used by ContextMenu. In Accessibility, for a 228 * menu to work as expected, the window has to be ignored. 229 * Note that asking the children of the window is 230 * very important in this context. It ensures that all 231 * descendants created. Without it, the menu will 232 * not be seen by the assistive technology. 233 */ 234 __block BOOL ignored = [super accessibilityIsIgnored]; 235 NSArray* children = [self accessibilityAttributeValue: NSAccessibilityChildrenAttribute]; 236 if (children) { 237 [children enumerateObjectsUsingBlock: ^(id child, NSUInteger index, BOOL *stop) { 238 NSString* role = [child accessibilityAttributeValue: NSAccessibilityRoleAttribute]; 239 if ([NSAccessibilityMenuRole isEqualToString: role]) { 240 ignored = YES; 241 *stop = YES; 242 } 243 /* Tooltips are exposed by AXHelp attribute and there is no API in Mac 244 * to represent the tooltip window. 245 * Nonetheless, the window must be ignored to prevent interfering with 246 * VoiceOver focus. 247 */ 248 if ([@"AXJFXTOOLTIP" isEqualToString: role]) { 249 ignored = YES; 250 *stop = YES; 251 } 252 }]; 253 } 254 return ignored; 255 } 256 257 - (id)accessibilityAttributeValue:(NSString *)attribute 258 { 259 /* 260 * The default value of AXRoleDescription for a NSPanel is 'system dialog'. 261 * While this is correct for an average cocoa application it is not appropriate 262 * for JFX, where all NSPanels are decoration-less windows used to implement 263 * tooltip, context menus, combo boxes, etc. 264 */ 265 if ([NSAccessibilityRoleDescriptionAttribute isEqualToString: attribute]) { 266 return @""; 267 } 268 return [super accessibilityAttributeValue: attribute]; 269 } 270 271 @end 272 // -------------------------------------------------------------------------------------- 273 274 275 @implementation GlassWindow 276 277 - (void)setFullscreenWindow:(NSWindow*)fsWindow 278 { 279 if (self->fullscreenWindow == fsWindow) { 280 return; 281 } 282 283 [self _ungrabFocus]; 284 285 NSWindow *from, *to; 286 from = self->fullscreenWindow ? self->fullscreenWindow : self->nsWindow; 287 to = fsWindow ? fsWindow : self->nsWindow; 288 289 NSArray * children = [from childWindows]; 290 for (NSUInteger i=0; i<[children count]; i++) 291 { 292 NSWindow *child = (NSWindow*)[children objectAtIndex:i]; 293 if ([[child delegate] isKindOfClass: [GlassWindow class]]) { 294 [from removeChildWindow: child]; 295 [to addChildWindow:child ordered:NSWindowAbove]; 296 } 297 } 298 299 self->fullscreenWindow = fsWindow; 300 301 GET_MAIN_JENV; 302 (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyDelegatePtr, ptr_to_jlong(fsWindow)); 303 GLASS_CHECK_EXCEPTION(env); 304 } 305 306 - (void)close 307 { 308 [self _ungrabFocus]; 309 } 310 311 - (void)sendEvent:(NSEvent *)event 312 { 313 if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) 314 { 315 NSPoint p = [NSEvent mouseLocation]; 316 NSRect frame = [self->nsWindow frame]; 317 NSRect contentRect = [self->nsWindow contentRectForFrameRect:frame]; 318 319 if (p.y >= (frame.origin.y + contentRect.size.height)) 320 { 321 // Click to the titlebar 322 [self _ungrabFocus]; 323 } 324 325 [self _checkUngrab]; 326 } 327 } 328 329 // Window vs Panel API 330 - (BOOL)canBecomeMainWindow 331 { 332 if (!self->isEnabled) 333 { 334 // We'll send FOCUS_DISABLED 335 return YES; 336 } 337 return self->isFocusable; 338 } 339 340 // Window vs Panel API 341 - (BOOL)hidesOnDeactivate 342 { 343 return NO; 344 } 345 346 // Window vs Panel API 347 - (BOOL)worksWhenModal 348 { 349 return NO; 350 } 351 352 - (BOOL)canBecomeKeyWindow 353 { 354 if (!self->isEnabled) 355 { 356 // We'll send FOCUS_DISABLED 357 return YES; 358 } 359 return self->isFocusable; 360 } 361 362 - (NSColor*)setBackgroundColor:(NSColor *)color 363 { 364 if (self->isTransparent == NO) 365 { 366 // allow color if we're opaque 367 return color; 368 } 369 else 370 { 371 // for transparent window, ignore and set to clear color 372 // FIXME: do we want to store the background color in case we switch to non-transparent mode? 373 return [NSColor clearColor]; 374 } 375 } 376 377 378 @end 379 380 #pragma mark --- GlassEmbeddedWindow 381 382 static NSMutableArray * embeddedWindowsList = nil; 383 384 @implementation GlassEmbeddedWindow 385 386 - (id)initWithDelegate:(GlassWindow*)delegate 387 frameRect:(NSRect)rect 388 styleMask:(NSUInteger)styleMask 389 screen:(NSScreen*)screen 390 { 391 self = [super initWithDelegate:delegate frameRect:rect styleMask:styleMask screen:screen]; 392 if (self == nil) { 393 return nil; 394 } 395 396 if (embeddedWindowsList == nil) { 397 embeddedWindowsList = [[NSMutableArray alloc] initWithCapacity: 4]; 398 } 399 [embeddedWindowsList addObject:self]; // retains 'self' 400 401 return self; 402 } 403 404 - (void)close 405 { 406 if (embeddedWindowsList) { 407 [embeddedWindowsList removeObject:self]; // releases 'self' 408 if ([embeddedWindowsList count] == 0) { 409 [embeddedWindowsList release]; 410 embeddedWindowsList = nil; 411 } 412 } 413 [super close]; 414 } 415 416 + (BOOL)exists:(GlassEmbeddedWindow*)window 417 { 418 if (embeddedWindowsList && window) { 419 return [embeddedWindowsList indexOfObjectIdenticalTo:window] != NSNotFound; 420 } 421 return NO; 422 } 423 424 - (void)setFullscreenWindow:(NSWindow*)fsWindow 425 { 426 if (self->parent != nil) 427 { 428 BOOL fullscreen = (fsWindow != nil); 429 430 CALayer *layer = [self->gWindow->view layer]; 431 if ([layer isKindOfClass:[GlassLayer3D class]] == YES) 432 { 433 [((CAOpenGLLayer*)layer) setAsynchronous:fullscreen]; 434 435 layer = [self->parent->gWindow->view layer]; 436 if ([layer isKindOfClass:[GlassLayer3D class]] == YES) 437 { 438 [((CAOpenGLLayer*)layer) setAsynchronous:!fullscreen]; 439 } 440 } 441 442 self->fullscreenWindow = fsWindow; 443 } 444 } 445 446 - (void)sendEvent:(NSEvent *)theEvent 447 { 448 BOOL fullscreen = (self->fullscreenWindow != nil); 449 if (fullscreen == NO) 450 { 451 [super sendEvent:theEvent]; 452 } 453 else 454 { 455 [self->fullscreenWindow sendEvent:theEvent]; 456 } 457 } 458 459 460 @end 461 462 #pragma mark --- Dispatcher 463 464 // TODO: re-implement using Obj-C blocks ? 465 static jlong _createWindowCommonDo(JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask, jboolean jIsChild) 466 { 467 GlassWindow *window = nil; 468 469 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 470 { 471 NSUInteger styleMask = NSBorderlessWindowMask; 472 // only titled windows get title 473 if ((jStyleMask&com_sun_glass_ui_Window_TITLED) != 0) 474 { 475 styleMask = styleMask|NSTitledWindowMask; 476 } 477 478 bool isUtility = (jStyleMask & com_sun_glass_ui_Window_UTILITY) != 0; 479 bool isPopup = (jStyleMask & com_sun_glass_ui_Window_POPUP) != 0; 480 481 // only nontransparent windows get decorations 482 if ((jStyleMask&com_sun_glass_ui_Window_TRANSPARENT) == 0) 483 { 484 if ((jStyleMask&com_sun_glass_ui_Window_CLOSABLE) != 0) 485 { 486 styleMask = styleMask|NSClosableWindowMask; 487 } 488 489 if (((jStyleMask&com_sun_glass_ui_Window_MINIMIZABLE) != 0) || 490 ((jStyleMask&com_sun_glass_ui_Window_MAXIMIZABLE) != 0)) 491 { 492 // on Mac OS X there is one set for min/max buttons, 493 // so if clients requests either one, we turn them both on 494 styleMask = styleMask|NSMiniaturizableWindowMask; 495 } 496 497 if ((jStyleMask&com_sun_glass_ui_Window_UNIFIED) != 0) { 498 styleMask = styleMask|NSTexturedBackgroundWindowMask; 499 } 500 501 if (isUtility) 502 { 503 styleMask = styleMask | NSUtilityWindowMask | NSNonactivatingPanelMask; 504 } 505 } 506 507 if (isPopup) 508 { 509 // can receive keyboard input without activating the owning application 510 styleMask = styleMask|NSNonactivatingPanelMask; 511 } 512 513 // initial size must be 0x0 otherwise we don't get resize update if the initial size happens to be the exact same size as the later programatical one! 514 CGFloat x = 0.0f; 515 CGFloat y = 0.0f; 516 CGFloat w = 0.0f; 517 CGFloat h = 0.0f; 518 519 NSScreen *screen = (NSScreen*)jlong_to_ptr(jScreenPtr); 520 window = [[GlassWindow alloc] _initWithContentRect:NSMakeRect(x, y, w, h) styleMask:styleMask screen:screen jwindow:jWindow jIsChild:jIsChild]; 521 522 if ((jStyleMask & com_sun_glass_ui_Window_UNIFIED) != 0) { 523 //Prevent the textured effect from disappearing on border thickness recalculation 524 [window->nsWindow setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; 525 } 526 527 if ((jStyleMask & com_sun_glass_ui_Window_UTILITY) != 0) { 528 [[window->nsWindow standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; 529 [[window->nsWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; 530 if (!jOwnerPtr) { 531 [window->nsWindow setLevel:NSNormalWindowLevel]; 532 } 533 } 534 535 if (jIsChild == JNI_FALSE) 536 { 537 if (jOwnerPtr != 0L) 538 { 539 window->owner = getGlassWindow(env, jOwnerPtr)->nsWindow; // not retained (use weak reference?) 540 } 541 } 542 else 543 { 544 if ((jOwnerPtr != 0L) && (jOwnerPtr != BROWSER_PARENT_ID)) 545 { 546 GlassEmbeddedWindow *parent = getGlassEmbeddedWindow(env, jOwnerPtr); 547 GlassEmbeddedWindow *ewindow = (GlassEmbeddedWindow*)window->nsWindow; 548 parent->child = ewindow; // not retained (use weak reference?) 549 550 ewindow->parent = parent; // not retained (use weak reference?) 551 } 552 } 553 window->isResizable = NO; 554 window->isDecorated = (jStyleMask&com_sun_glass_ui_Window_TITLED) != 0; 555 /* 10.7 full screen window support */ 556 if ([NSWindow instancesRespondToSelector:@selector(toggleFullScreen:)]) { 557 NSWindowCollectionBehavior behavior = [window->nsWindow collectionBehavior]; 558 if (!isPopup && !isUtility && !window->owner) 559 { 560 // Only ownerless windows should have the Full Screen Toggle control 561 behavior |= (1 << 7) /* NSWindowCollectionBehaviorFullScreenPrimary */; 562 } 563 else 564 { 565 // Other windows are only allowed to be shown together with a primary 566 // full screen window 567 behavior |= (1 << 8) /* NSWindowCollectionBehaviorFullScreenAuxiliary */; 568 } 569 [window->nsWindow setCollectionBehavior: behavior]; 570 } 571 572 window->isTransparent = (jStyleMask & com_sun_glass_ui_Window_TRANSPARENT) != 0; 573 if (window->isTransparent == YES) 574 { 575 [window->nsWindow setBackgroundColor:[NSColor clearColor]]; 576 [window->nsWindow setHasShadow:NO]; 577 [window->nsWindow setOpaque:NO]; 578 } 579 else 580 { 581 [window->nsWindow setHasShadow:YES]; 582 [window->nsWindow setOpaque:YES]; 583 } 584 585 window->fullscreenWindow = nil; 586 587 window->isSizeAssigned = NO; 588 window->isLocationAssigned = NO; 589 590 if (jIsChild == JNI_TRUE && jOwnerPtr != 0L && jOwnerPtr != BROWSER_PARENT_ID 591 && [window->nsWindow isKindOfClass:[GlassEmbeddedWindow class]]) 592 { 593 GlassEmbeddedWindow* parent = ((GlassEmbeddedWindow*)window->nsWindow)->parent; 594 if ([GlassEmbeddedWindow exists:parent]) 595 { 596 window->isLocationAssigned = YES; 597 NSScreen *pscreen = [[NSScreen screens] objectAtIndex:0]; 598 NSRect screenFrame = pscreen.frame; 599 NSRect frameRect = parent.frame; 600 int invy = (int)round(screenFrame.size.height - frameRect.size.height - frameRect.origin.y); 601 [window _setBounds:(int)round(frameRect.origin.x) 602 y:invy 603 xSet:YES ySet:YES w:0 h:0 cw:0 ch:0]; 604 } 605 } 606 } 607 [pool drain]; 608 609 GLASS_CHECK_EXCEPTION(env); 610 611 return ptr_to_jlong(window->nsWindow); 612 } 613 614 static jlong _createWindowCommon 615 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask, jboolean jIsChild) 616 { 617 LOG("_createWindowCommon"); 618 619 jlong value = 0L; 620 621 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 622 GLASS_POOL_ENTER; 623 { 624 jobject jWindowRef = (*env)->NewGlobalRef(env, jWindow); 625 value = _createWindowCommonDo(env, jWindowRef, jOwnerPtr, jScreenPtr, jStyleMask, jIsChild); 626 } 627 GLASS_POOL_EXIT; 628 GLASS_CHECK_EXCEPTION(env); 629 630 LOG(" window: %p", value); 631 return value; 632 } 633 634 #pragma mark --- JNI 635 636 /* 637 * Class: com_sun_glass_ui_mac_MacWindow 638 * Method: _initIDs 639 * Signature: ()V 640 */ 641 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1initIDs 642 (JNIEnv *env, jclass jClass) 643 { 644 LOG("Java_com_sun_glass_ui_mac_MacWindow__1initIDs"); 645 646 if (jWindowClass == NULL) 647 { 648 jWindowClass = (*env)->NewGlobalRef(env, jClass); 649 } 650 651 if (jMenuBarDelegateClass == NULL) 652 { 653 jMenuBarDelegateClass = (*env)->NewGlobalRef(env, [GlassHelper ClassForName:"com.sun.glass.ui.mac.MacMenuBarDelegate" withEnv:env]); 654 } 655 656 if (jViewClass == NULL) 657 { 658 jViewClass = (*env)->NewGlobalRef(env, [GlassHelper ClassForName:"com.sun.glass.ui.View" withEnv:env]); 659 } 660 661 if (jScreenClass == NULL) 662 { 663 jScreenClass = (*env)->NewGlobalRef(env, [GlassHelper ClassForName:"com.sun.glass.ui.Screen" withEnv:env]); 664 } 665 666 if (jWindowNotifyMove == NULL) 667 { 668 jWindowNotifyMove = (*env)->GetMethodID(env, jWindowClass, "notifyMove", "(IIZ)V"); 669 if ((*env)->ExceptionCheck(env)) return; 670 } 671 672 if (jWindowNotifyResize == NULL) 673 { 674 jWindowNotifyResize = (*env)->GetMethodID(env, jWindowClass, "notifyResize", "(III)V"); 675 if ((*env)->ExceptionCheck(env)) return; 676 } 677 678 if (jWindowNotifyMoveToAnotherScreen == NULL) 679 { 680 jWindowNotifyMoveToAnotherScreen = (*env)->GetMethodID(env, jWindowClass, "notifyMoveToAnotherScreen", "(Lcom/sun/glass/ui/Screen;)V"); 681 if ((*env)->ExceptionCheck(env)) return; 682 } 683 684 if (jWindowNotifyScaleChanged == NULL) 685 { 686 jWindowNotifyScaleChanged = (*env)->GetMethodID(env, jWindowClass, "notifyScaleChanged", "(FFFF)V"); 687 if ((*env)->ExceptionCheck(env)) return; 688 } 689 690 if (jWindowNotifyClose == NULL) 691 { 692 jWindowNotifyClose = (*env)->GetMethodID(env, jWindowClass, "notifyClose", "()V"); 693 if ((*env)->ExceptionCheck(env)) return; 694 } 695 696 if (jWindowNotifyFocus == NULL) 697 { 698 jWindowNotifyFocus = (*env)->GetMethodID(env, jWindowClass, "notifyFocus", "(I)V"); 699 if ((*env)->ExceptionCheck(env)) return; 700 } 701 702 if (jWindowNotifyFocusUngrab == NULL) 703 { 704 jWindowNotifyFocusUngrab = (*env)->GetMethodID(env, jWindowClass, "notifyFocusUngrab", "()V"); 705 if ((*env)->ExceptionCheck(env)) return; 706 } 707 708 if (jWindowNotifyFocusDisabled == NULL) 709 { 710 jWindowNotifyFocusDisabled = (*env)->GetMethodID(env, jWindowClass, "notifyFocusDisabled", "()V"); 711 if ((*env)->ExceptionCheck(env)) return; 712 } 713 714 if (jWindowNotifyDestroy == NULL) 715 { 716 jWindowNotifyDestroy = (*env)->GetMethodID(env, jWindowClass, "notifyDestroy", "()V"); 717 if ((*env)->ExceptionCheck(env)) return; 718 } 719 720 if (jWindowNotifyDelegatePtr == NULL) 721 { 722 jWindowNotifyDelegatePtr = (*env)->GetMethodID(env, jWindowClass, "notifyDelegatePtr", "(J)V"); 723 } 724 } 725 726 /* 727 * Class: com_sun_glass_ui_mac_MacWindow 728 * Method: _createWindow 729 * Signature: (JJI)J 730 */ 731 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacWindow__1createWindow 732 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask) 733 { 734 LOG("Java_com_sun_glass_ui_mac_MacWindow__1createWindow"); 735 736 return _createWindowCommon(env, jWindow, jOwnerPtr, jScreenPtr, jStyleMask, JNI_FALSE); 737 } 738 739 /* 740 * Class: com_sun_glass_ui_mac_MacWindow 741 * Method: _createChildWindow 742 * Signature: (J)J 743 */ 744 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacWindow__1createChildWindow 745 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr) 746 { 747 LOG("Java_com_sun_glass_ui_mac_MacWindow__1createChildWindow"); 748 LOG(" owner: %p", jOwnerPtr); 749 750 jlong jScreenPtr = 0L; 751 jint jStyleMask = NSBorderlessWindowMask; 752 if (jOwnerPtr == BROWSER_PARENT_ID) 753 { 754 LOG(" case PARENT (PLUGIN)"); 755 // special case: embedded window for plugin (the container which will hold the child window) 756 } 757 else 758 { 759 LOG(" case CHILD (EMBEDDED)"); 760 // special case: embedded window for plugin (the actual plugin window with remote layer) 761 // jOwnerPtr must be a valid GlassEmbeddedWindow instance 762 if (![GlassEmbeddedWindow exists:(GlassEmbeddedWindow*)jlong_to_ptr(jOwnerPtr)]) { 763 return (jlong)0; 764 } 765 } 766 767 return _createWindowCommon(env, jWindow, jOwnerPtr, jScreenPtr, jStyleMask, JNI_TRUE); 768 } 769 770 /* 771 * Class: com_sun_glass_ui_mac_MacWindow 772 * Method: _setLevel 773 * Signature: (JI)V 774 */ 775 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setLevel 776 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jLevel) 777 { 778 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setLevel"); 779 if (!jPtr) return; 780 781 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 782 GLASS_POOL_ENTER; 783 { 784 GlassWindow *window = getGlassWindow(env, jPtr); 785 NSInteger level = NSNormalWindowLevel; 786 switch (jLevel) 787 { 788 case com_sun_glass_ui_Window_Level_FLOATING: 789 level = NSFloatingWindowLevel; 790 break; 791 case com_sun_glass_ui_Window_Level_TOPMOST: 792 level = NSScreenSaverWindowLevel; 793 break; 794 } 795 [window->nsWindow setLevel:level]; 796 } 797 GLASS_POOL_EXIT; 798 GLASS_CHECK_EXCEPTION(env); 799 } 800 801 /* 802 * Class: com_sun_glass_ui_mac_MacWindow 803 * Method: _setFocusable 804 * Signature: (Z)V 805 */ 806 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setFocusable 807 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean isFocusable) 808 { 809 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setCanBecomeActive"); 810 if (!jPtr) return; 811 812 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 813 GLASS_POOL_ENTER; 814 { 815 GlassWindow *window = getGlassWindow(env, jPtr); 816 window->isFocusable = (isFocusable==JNI_TRUE); 817 } 818 GLASS_POOL_EXIT; 819 GLASS_CHECK_EXCEPTION(env); 820 } 821 822 /* 823 * Class: com_sun_glass_ui_mac_MacWindow 824 * Method: _setEnabled 825 * Signature: (JZ)V 826 */ 827 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setEnabled 828 (JNIEnv *env, jobject jwindow, jlong jPtr, jboolean isEnabled) 829 { 830 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setEnabled"); 831 if (!jPtr) return; 832 833 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 834 GLASS_POOL_ENTER; 835 { 836 GlassWindow *window = getGlassWindow(env, jPtr); 837 window->isEnabled = (BOOL)isEnabled; 838 NSButton *zoomButton = [window->nsWindow standardWindowButton:NSWindowZoomButton]; 839 if ((window->isEnabled) && (window->isResizable)){ 840 [window->nsWindow setStyleMask: window->enabledStyleMask]; 841 if (window->enabledStyleMask & NSResizableWindowMask) { 842 [zoomButton setEnabled:YES]; 843 } 844 } 845 else if((window->isEnabled) && (!window->isResizable)){ 846 [window->nsWindow setStyleMask: 847 (window->enabledStyleMask & ~(NSUInteger) NSResizableWindowMask)]; 848 [zoomButton setEnabled:NO]; 849 } 850 else{ 851 window->enabledStyleMask = [window->nsWindow styleMask]; 852 [window->nsWindow setStyleMask: 853 (window->enabledStyleMask & ~(NSUInteger)(NSMiniaturizableWindowMask | NSResizableWindowMask))]; 854 [zoomButton setEnabled:NO]; 855 } 856 } 857 GLASS_POOL_EXIT; 858 GLASS_CHECK_EXCEPTION(env); 859 } 860 861 /* 862 * Class: com_sun_glass_ui_mac_MacWindow 863 * Method: _setAlpha 864 * Signature: (F)V 865 */ 866 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setAlpha 867 (JNIEnv *env, jobject jWindow, jlong jPtr, jfloat jAlpha) 868 { 869 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setAlpha"); 870 if (!jPtr) return; 871 872 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 873 GLASS_POOL_ENTER; 874 { 875 GlassWindow *window = getGlassWindow(env, jPtr); 876 [window->nsWindow setAlphaValue:jAlpha]; 877 } 878 GLASS_POOL_EXIT; 879 GLASS_CHECK_EXCEPTION(env); 880 } 881 882 /* 883 * Class: com_sun_glass_ui_mac_MacWindow 884 * Method: _setBackground 885 * Signature: (JFFF)Z 886 */ 887 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setBackground 888 (JNIEnv *env, jobject jWindow, jlong jPtr, jfloat r, jfloat g, jfloat b) 889 { 890 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setBackground"); 891 if (!jPtr) return JNI_FALSE; 892 893 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 894 GLASS_POOL_ENTER; 895 { 896 GlassWindow *window = getGlassWindow(env, jPtr); 897 [window->nsWindow setBackgroundColor:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0f]]; 898 } 899 GLASS_POOL_EXIT; 900 GLASS_CHECK_EXCEPTION(env); 901 902 return JNI_TRUE; // gznote: remove this return value if unused 903 } 904 905 /* 906 * Class: com_sun_glass_ui_mac_MacWindow 907 * Method: _setView 908 * Signature: (J)Z 909 */ 910 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setView 911 (JNIEnv *env, jobject jWindow, jlong jPtr, jobject jview) 912 { 913 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setView"); 914 LOG(" window: %p", jPtr); 915 LOG(" view: %p", getMacView(env, jview)); 916 if (!jPtr) return JNI_FALSE; 917 918 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 919 GLASS_POOL_ENTER; 920 { 921 GlassWindow *window = getGlassWindow(env, jPtr); 922 923 // We don't support changing views in the FS mode because 924 // by Glass design the FS functionality belongs to the View. 925 // Also, this leads to a crash on the Mac 926 if ([window->nsWindow styleMask] & (1 << 14)/*NSFullScreenWindowMask*/) { 927 [window->nsWindow performSelector:@selector(toggleFullScreen:) withObject:nil]; 928 929 // Wait until the FS mode has really exited 930 [GlassApplication enterFullScreenExitingLoop]; 931 } 932 933 NSView<GlassView> *oldView = window->view; 934 window->view = getMacView(env, jview); 935 //NSLog(@" window: %@", window); 936 //NSLog(@" frame: %.2f,%.2f %.2fx%.2f", [window frame].origin.x, [window frame].origin.y, [window frame].size.width, [window frame].size.height); 937 //NSLog(@" view: %@", window->view); 938 //NSLog(@" frame: %.2f,%.2f %.2fx%.2f", [window->view frame].origin.x, [window->view frame].origin.y, [window->view frame].size.width, [window->view frame].size.height); 939 940 // Make sure we synchronize scale factors to the new view as any 941 // dynamic updates might have happened when we had the old view 942 // and/or we may have been set visible before we had a view and 943 // missed the initial notification. 944 if ([window->nsWindow screen]) { 945 [window->view notifyScaleFactorChanged:GetScreenScaleFactor([window->nsWindow screen])]; 946 } 947 948 if (oldView && oldView != window->view) { 949 [[oldView delegate] resetMouseTracking]; 950 } 951 952 if (window->view != nil) 953 { 954 CALayer *layer = [window->view layer]; 955 if (([layer isKindOfClass:[CAOpenGLLayer class]] == YES) && 956 (([window->nsWindow styleMask] & NSTexturedBackgroundWindowMask) == NO)) 957 { 958 [((CAOpenGLLayer*)layer) setOpaque:[window->nsWindow isOpaque]]; 959 } 960 961 window->suppressWindowMoveEvent = YES; // RT-11215 962 { 963 NSRect viewFrame = [window->view frame]; 964 if ((viewFrame.size.width != 0.0f) && (viewFrame.size.height != 0.0f)) 965 { 966 NSRect windowFrame = [window->nsWindow frameRectForContentRect:viewFrame]; 967 windowFrame.origin.x = [window->nsWindow frame].origin.x; 968 windowFrame.origin.y = [window->nsWindow frame].origin.y; 969 [window _setWindowFrameWithRect:NSMakeRect(windowFrame.origin.x, windowFrame.origin.y, windowFrame.size.width, windowFrame.size.height) withDisplay:JNI_TRUE withAnimate:JNI_FALSE]; 970 } 971 972 [window->nsWindow setContentView:[window->view superview]]; // use our superview not ourselves! 973 [window->nsWindow setInitialFirstResponder:window->view]; 974 [window->nsWindow makeFirstResponder:window->view]; 975 } 976 window->suppressWindowMoveEvent = NO; 977 } 978 else 979 { 980 [window->nsWindow performSelectorOnMainThread:@selector(setContentView:) withObject:nil waitUntilDone:YES]; 981 } 982 } 983 GLASS_POOL_EXIT; 984 GLASS_CHECK_EXCEPTION(env); 985 986 return JNI_TRUE; // gznote: remove this return value if unused 987 } 988 989 /* 990 * Class: com_sun_glass_ui_mac_MacWindow 991 * Method: _setMenubar 992 * Signature: (Lcom/sun/glass/ui/mac/MacMenubarDelegate;)V 993 */ 994 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMenubar 995 (JNIEnv *env, jobject jWindow, jlong jPtr, jlong jMenubarPtr) 996 { 997 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMenubar"); 998 if (!jPtr) return JNI_FALSE; 999 1000 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1001 GLASS_POOL_ENTER; 1002 { 1003 GlassWindow *window = getGlassWindow(env, jPtr); 1004 window->menubar = (GlassMenubar*)jlong_to_ptr(jMenubarPtr); 1005 [NSApp setMainMenu:window->menubar->menu]; 1006 [[NSApp mainMenu] update]; 1007 } 1008 GLASS_POOL_EXIT; 1009 GLASS_CHECK_EXCEPTION(env); 1010 1011 return JNI_TRUE; // gznote: remove this return value if unused 1012 } 1013 1014 /* 1015 * Class: com_sun_glass_ui_mac_MacWindow 1016 * Method: _close 1017 * Signature: ()V 1018 */ 1019 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1close 1020 (JNIEnv *env, jclass cls, jlong jPtr) 1021 { 1022 LOG("Java_com_sun_glass_ui_mac_MacWindow__1close"); 1023 if (!jPtr) return JNI_FALSE; 1024 1025 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1026 GLASS_POOL_ENTER; 1027 { 1028 GlassWindow *window = getGlassWindow(env, jPtr); 1029 // this call will always close the window 1030 // without calling the windowShouldClose 1031 1032 // RT-39813 When closing a window as the result of a global right-click 1033 // mouse event outside the bounds of the window, using an immediate 1034 // [window->nsWindow close] crashes the JDK as the AppKit at this 1035 // point still has another [NSWindow _resignKeyFocus] from the 1036 // right-click handling in [NSApplication sendEvent]. This defers 1037 // the close until the [NSWindow _resignKeyFocus] can be performed. 1038 1039 [window->nsWindow performSelectorOnMainThread:@selector(close) withObject:nil waitUntilDone:NO]; 1040 1041 // The NSWindow will be automatically released after closing 1042 // The GlassWindow is released in the [NSWindow dealloc] override 1043 } 1044 GLASS_POOL_EXIT; 1045 GLASS_CHECK_EXCEPTION(env); 1046 1047 return JNI_TRUE; // gznote: remove this return value if unused 1048 } 1049 1050 /* 1051 * Class: com_sun_glass_ui_mac_MacWindow 1052 * Method: _requestFocus 1053 * Signature: (J)Z 1054 */ 1055 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1requestFocus 1056 (JNIEnv *env, jobject jWindow, jlong jPtr) 1057 { 1058 LOG("Java_com_sun_glass_ui_mac_MacWindow__1requestFocus"); 1059 if (!jPtr) return JNI_FALSE; 1060 1061 jboolean focused = JNI_FALSE; 1062 1063 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1064 GLASS_POOL_ENTER; 1065 { 1066 GlassWindow *window = getGlassWindow(env, jPtr); 1067 1068 if ([window->nsWindow isVisible]) 1069 { 1070 [window->nsWindow makeMainWindow]; 1071 [window->nsWindow makeKeyAndOrderFront:window->nsWindow]; 1072 [window->nsWindow orderFrontRegardless]; 1073 } 1074 1075 focused = [window->nsWindow isKeyWindow] ? JNI_TRUE : JNI_FALSE; 1076 } 1077 GLASS_POOL_EXIT; 1078 GLASS_CHECK_EXCEPTION(env); 1079 1080 return focused; 1081 } 1082 1083 /* 1084 * Class: com_sun_glass_ui_mac_MacWindow 1085 * Method: _grabFocus 1086 * Signature: (J)Z 1087 */ 1088 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1grabFocus 1089 (JNIEnv *env, jobject jThis, jlong jPtr) 1090 { 1091 LOG("Java_com_sun_glass_ui_mac_MacWindow__1grabFocus"); 1092 if (!jPtr) return JNI_FALSE; 1093 1094 jboolean ret = JNI_FALSE; 1095 1096 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1097 GLASS_POOL_ENTER; 1098 { 1099 GlassWindow * window = getGlassWindow(env, jPtr); 1100 //TODO: full screen 1101 [window _grabFocus]; 1102 ret = JNI_TRUE; 1103 } 1104 GLASS_POOL_EXIT; 1105 GLASS_CHECK_EXCEPTION(env); 1106 1107 return ret; 1108 } 1109 1110 /* 1111 * Class: com_sun_glass_ui_mac_MacWindow 1112 * Method: _ungrabFocus 1113 * Signature: (J)V 1114 */ 1115 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1ungrabFocus 1116 (JNIEnv *env, jobject jThis, jlong jPtr) 1117 { 1118 LOG("Java_com_sun_glass_ui_mac_MacWindow__1ungrabFocus"); 1119 if (!jPtr) return; 1120 1121 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1122 GLASS_POOL_ENTER; 1123 { 1124 GlassWindow * window = getGlassWindow(env, jPtr); 1125 //TODO; full screen 1126 [window _ungrabFocus]; 1127 } 1128 GLASS_POOL_EXIT; 1129 GLASS_CHECK_EXCEPTION(env); 1130 } 1131 1132 /* 1133 * Class: com_sun_glass_ui_mac_MacWindow 1134 * Method: _maximize 1135 * Signature: (JZZ)V 1136 */ 1137 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1maximize 1138 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean maximize, jboolean isZoomed) 1139 { 1140 LOG("Java_com_sun_glass_ui_mac_MacWindow__1maximize"); 1141 if (!jPtr) return JNI_FALSE; 1142 1143 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1144 GLASS_POOL_ENTER; 1145 { 1146 GlassWindow *window = getGlassWindow(env, jPtr); 1147 window->suppressWindowResizeEvent = YES; 1148 1149 if ((maximize == JNI_TRUE) && (isZoomed == JNI_FALSE)) 1150 { 1151 window->preZoomedRect = [window->nsWindow frame]; 1152 1153 if ([window->nsWindow styleMask] != NSBorderlessWindowMask) 1154 { 1155 [window->nsWindow zoom:nil]; 1156 // windowShouldZoom will be called automatically in this case 1157 } 1158 else 1159 { 1160 NSRect visibleRect = [[window _getScreen] visibleFrame]; 1161 [window _setWindowFrameWithRect:NSMakeRect(visibleRect.origin.x, visibleRect.origin.y, visibleRect.size.width, visibleRect.size.height) withDisplay:JNI_TRUE withAnimate:JNI_TRUE]; 1162 1163 // calling windowShouldZoom will send Java maximize event 1164 [window windowShouldZoom:window->nsWindow toFrame:[window->nsWindow frame]]; 1165 } 1166 } 1167 else if ((maximize == JNI_FALSE) && (isZoomed == JNI_TRUE)) 1168 { 1169 [window _restorePreZoomedRect]; 1170 } 1171 1172 window->suppressWindowResizeEvent = NO; 1173 } 1174 GLASS_POOL_EXIT; 1175 GLASS_CHECK_EXCEPTION(env); 1176 1177 return JNI_TRUE; // gznote: remove this return value if unused 1178 } 1179 1180 /* 1181 * Class: com_sun_glass_ui_mac_MacWindow 1182 * Method: _setBounds 1183 * Signature: (JIIZZIIIIFF)V 1184 */ 1185 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setBounds2 1186 (JNIEnv *env, jobject jWindow, jlong jPtr, 1187 jint x, jint y, jboolean xSet, jboolean ySet, 1188 jint w, jint h, jint cw, jint ch, jfloat xGravity, jfloat yGravity) 1189 { 1190 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setBounds"); 1191 LOG(" x,y: %d,%d", x, y); 1192 LOG(" xSet,ySet: %d,%d", xSet, ySet); 1193 LOG(" xGravity,yGravity: %.2f,%.2f", xGravity, yGravity); 1194 LOG(" w x h: %dx%d", w, h); 1195 LOG(" cw x ch: %dx%d", cw, ch); 1196 if (!jPtr) return; 1197 1198 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1199 GLASS_POOL_ENTER; 1200 { 1201 GlassWindow *window = getGlassWindow(env, jPtr); 1202 if (xSet || ySet) window->isLocationAssigned = YES; 1203 if (w > 0 || h > 0 || cw > 0 || ch > 0) window->isSizeAssigned = YES; 1204 [window _setBounds:x y:y xSet:xSet ySet:ySet w:w h:h cw:cw ch:ch]; 1205 } 1206 GLASS_POOL_EXIT; 1207 GLASS_CHECK_EXCEPTION(env); 1208 } 1209 1210 /* 1211 * Class: com_sun_glass_ui_mac_MacWindow 1212 * Method: _setMinimumSize 1213 * Signature: (JII)Z 1214 */ 1215 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMinimumSize 1216 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jW, jint jH) 1217 { 1218 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMinimumSize"); 1219 if (!jPtr) return JNI_FALSE; 1220 1221 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1222 GLASS_POOL_ENTER; 1223 { 1224 GlassWindow *window = getGlassWindow(env, jPtr); 1225 [window->nsWindow setMinSize:NSMakeSize(jW, jH)]; 1226 } 1227 GLASS_POOL_EXIT; 1228 GLASS_CHECK_EXCEPTION(env); 1229 1230 return JNI_TRUE; // gznote: remove this return value if unused 1231 } 1232 1233 /* 1234 * Class: com_sun_glass_ui_mac_MacWindow 1235 * Method: _setMaximumSize 1236 * Signature: (JII)Z 1237 */ 1238 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMaximumSize 1239 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jW, jint jH) 1240 { 1241 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMaximumSize"); 1242 if (!jPtr) return JNI_FALSE; 1243 1244 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1245 GLASS_POOL_ENTER; 1246 { 1247 GlassWindow *window = getGlassWindow(env, jPtr); 1248 [window->nsWindow setMaxSize:NSMakeSize(jW == -1 ? FLT_MAX : (CGFloat)jW, 1249 jH == -1 ? FLT_MAX : (CGFloat)jH)]; 1250 } 1251 GLASS_POOL_EXIT; 1252 GLASS_CHECK_EXCEPTION(env); 1253 1254 return JNI_TRUE; // gznote: remove this return value if unused 1255 } 1256 1257 /* 1258 * Class: com_sun_glass_ui_mac_MacWindow 1259 * Method: _setResizable 1260 * Signature: (Z)Z 1261 */ 1262 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setResizable 1263 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jResizable) 1264 { 1265 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setResizable"); 1266 if (!jPtr) return JNI_FALSE; 1267 1268 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1269 GLASS_POOL_ENTER; 1270 { 1271 GlassWindow *window = getGlassWindow(env, jPtr); 1272 if (window->isResizable != jResizable) 1273 { 1274 [window performSelectorOnMainThread:@selector(_setResizable) withObject:nil waitUntilDone:YES]; 1275 } 1276 } 1277 GLASS_POOL_EXIT; 1278 GLASS_CHECK_EXCEPTION(env); 1279 1280 return JNI_TRUE; 1281 } 1282 1283 /* 1284 * Class: com_sun_glass_ui_mac_MacWindow 1285 * Method: _setVisible 1286 * Signature: (Z)Z 1287 */ 1288 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setVisible 1289 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jVisible) 1290 { 1291 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setVisible: %d", jVisible); 1292 LOG(" window: %p", jPtr); 1293 if (!jPtr) return JNI_FALSE; 1294 1295 jboolean now = JNI_FALSE; 1296 1297 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1298 GLASS_POOL_ENTER; 1299 { 1300 GlassWindow *window = getGlassWindow(env, jPtr); 1301 if (jVisible == JNI_TRUE) 1302 { 1303 if (!window->isLocationAssigned) { 1304 [window _setBounds:0 y:0 xSet:JNI_TRUE ySet:JNI_TRUE w:-1 h:-1 cw:-1 ch:-1]; 1305 } 1306 if (!window->isSizeAssigned) { 1307 [window _setBounds:0 y:0 xSet:JNI_FALSE ySet:JNI_FALSE w:320 h:200 cw:-1 ch:-1]; 1308 } 1309 [window _setVisible]; 1310 } 1311 else 1312 { 1313 [window _ungrabFocus]; 1314 if (window->owner != nil) 1315 { 1316 LOG(" removeChildWindow: %p", window); 1317 [window->owner removeChildWindow:window->nsWindow]; 1318 } 1319 [window->nsWindow orderOut:window->nsWindow]; 1320 } 1321 now = [window->nsWindow isVisible] ? JNI_TRUE : JNI_FALSE; 1322 1323 // RT-22502 temp workaround: bring plugin window in front of a browser 1324 if (now == YES) 1325 { 1326 static BOOL isBackgroundOnlyAppChecked = NO; 1327 static BOOL isBackgroundOnlyApp = NO; 1328 if (isBackgroundOnlyAppChecked == NO) 1329 { 1330 isBackgroundOnlyAppChecked = YES; 1331 1332 ProcessSerialNumber psn; 1333 if (GetCurrentProcess(&psn) == noErr) 1334 { 1335 ProcessInfoRec info; 1336 memset(&info, 0x00, sizeof(ProcessInfoRec)); 1337 GetProcessInformation(&psn, &info); 1338 isBackgroundOnlyApp = ((modeOnlyBackground&info.processMode) == modeOnlyBackground); 1339 } 1340 } 1341 if (isBackgroundOnlyApp == YES) 1342 { 1343 [window->nsWindow performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES]; 1344 } 1345 } 1346 } 1347 GLASS_POOL_EXIT; 1348 GLASS_CHECK_EXCEPTION(env); 1349 1350 return now; 1351 } 1352 1353 /* 1354 * Class: com_sun_glass_ui_mac_MacWindow 1355 * Method: _setTitle 1356 * Signature: (Ljava/lang/String;)Z 1357 */ 1358 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setTitle 1359 (JNIEnv *env, jobject jWindow, jlong jPtr, jstring jTitle) 1360 { 1361 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setTitle"); 1362 LOG(" window: %p", jPtr); 1363 if (!jPtr) return JNI_FALSE; 1364 1365 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1366 GLASS_POOL_ENTER; 1367 { 1368 GlassWindow *window = getGlassWindow(env, jPtr); 1369 1370 NSString *title = [GlassHelper nsStringWithJavaString:jTitle withEnv:env]; 1371 LOG(" title: %s", [title UTF8String]); 1372 [window->nsWindow setTitle:title]; 1373 } 1374 GLASS_POOL_EXIT; 1375 GLASS_CHECK_EXCEPTION(env); 1376 1377 return JNI_TRUE; // gnote: remove this return value if unused 1378 } 1379 1380 /* 1381 * Class: com_sun_glass_ui_mac_MacWindow 1382 * Method: _minimize 1383 * Signature: (Z)V 1384 */ 1385 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1minimize 1386 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jMiniaturize) 1387 { 1388 LOG("Java_com_sun_glass_ui_mac_MacWindow__1minimize"); 1389 if (!jPtr) return JNI_FALSE; 1390 1391 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1392 GLASS_POOL_ENTER; 1393 { 1394 GlassWindow *window = getGlassWindow(env, jPtr); 1395 1396 if (jMiniaturize == JNI_TRUE) 1397 { 1398 [window->nsWindow miniaturize:nil]; 1399 } 1400 else 1401 { 1402 [window->nsWindow deminiaturize:nil]; 1403 } 1404 } 1405 GLASS_POOL_EXIT; 1406 GLASS_CHECK_EXCEPTION(env); 1407 1408 return JNI_TRUE; // gnote: remove this return value if unused 1409 } 1410 1411 /* 1412 * Class: com_sun_glass_ui_mac_MacWindow 1413 * Method: _setIcon 1414 * Signature: (JLjava/nio/ByteBuffer;II)V 1415 */ 1416 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setIcon 1417 (JNIEnv *env, jobject jWindow, jlong jPtr, jobject iconBuffer, jint jWidth, jint jHeight) 1418 { 1419 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setIcon"); 1420 if (!jPtr) return; 1421 1422 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1423 GLASS_POOL_ENTER; 1424 { 1425 GlassWindow *window = getGlassWindow(env, jPtr); 1426 1427 if (iconBuffer) 1428 { 1429 NSImage *image = nil; 1430 1431 image = getImage( 1432 (*env)->GetDirectBufferAddress(env, iconBuffer), 1433 jHeight, jWidth, 0); 1434 1435 if (image != nil) { 1436 // need an explicit window title for the rest of the code to work 1437 if ([window->nsWindow title] == nil) 1438 { 1439 [window->nsWindow setTitle:@"Untitled"]; 1440 } 1441 1442 // http://www.cocoabuilder.com/archive/cocoa/199554-nswindow-title-bar-icon-without-representedurl.html 1443 [window->nsWindow setRepresentedURL:[NSURL fileURLWithPath:[window->nsWindow title]]]; 1444 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:image]; 1445 [image release]; 1446 } else { 1447 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil]; 1448 } 1449 } else { 1450 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil]; 1451 } 1452 } 1453 GLASS_POOL_EXIT; 1454 GLASS_CHECK_EXCEPTION(env); 1455 } 1456 1457 /* 1458 * Class: com_sun_glass_ui_mac_MacWindow 1459 * Method: _toFront 1460 * Signature: (J)V 1461 */ 1462 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1toFront 1463 (JNIEnv *env, jobject jWindow, jlong jPtr) 1464 { 1465 LOG("Java_com_sun_glass_ui_mac_MacWindow__1toFront"); 1466 LOG(" window: %p", jPtr); 1467 if (!jPtr) return; 1468 1469 GLASS_POOL_ENTER; 1470 { 1471 GlassWindow *window = getGlassWindow(env, jPtr); 1472 [window->nsWindow orderFrontRegardless]; 1473 } 1474 GLASS_POOL_EXIT; 1475 GLASS_CHECK_EXCEPTION(env); 1476 } 1477 1478 /* 1479 * Class: com_sun_glass_ui_mac_MacWindow 1480 * Method: _toBack 1481 * Signature: (J)V 1482 */ 1483 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1toBack 1484 (JNIEnv *env, jobject jWindow, jlong jPtr) 1485 { 1486 LOG("Java_com_sun_glass_ui_mac_MacWindow__1toBack"); 1487 if (!jPtr) return; 1488 1489 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1490 GLASS_POOL_ENTER; 1491 { 1492 GlassWindow *window = getGlassWindow(env, jPtr); 1493 [window->nsWindow orderBack:nil]; 1494 } 1495 GLASS_POOL_EXIT; 1496 GLASS_CHECK_EXCEPTION(env); 1497 } 1498 1499 1500 /* 1501 * Class: com_sun_glass_ui_mac_MacWindow 1502 * Method: _enterModal 1503 * Signature: (J)V 1504 */ 1505 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1enterModal 1506 (JNIEnv *env, jobject jWindow, jlong jPtr) 1507 { 1508 LOG("Java_com_sun_glass_ui_mac_MacWindow__1enterModal"); 1509 if (!jPtr) return; 1510 1511 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1512 GLASS_POOL_ENTER; 1513 { 1514 GlassWindow *window = getGlassWindow(env, jPtr); 1515 [NSApp runModalForWindow:window->nsWindow]; 1516 } 1517 GLASS_POOL_EXIT; 1518 GLASS_CHECK_EXCEPTION(env); 1519 } 1520 1521 /* 1522 * Class: com_sun_glass_ui_mac_MacWindow 1523 * Method: _enterModalWithWindow 1524 * Signature: (JJ)V 1525 */ 1526 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1enterModalWithWindow 1527 (JNIEnv *env, jobject jWindow, jlong jDialogPtr, jlong jWindowPtr) 1528 { 1529 LOG("Java_com_sun_glass_ui_mac_MacWindow__1enterModalWithWindow"); 1530 1531 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1532 GLASS_POOL_ENTER; 1533 { 1534 //GlassWindow *window = getGlassWindow(env, jDialogPtr); 1535 // TODO: implement _enterModalWithWindow 1536 } 1537 GLASS_POOL_EXIT; 1538 GLASS_CHECK_EXCEPTION(env); 1539 } 1540 1541 /* 1542 * Class: com_sun_glass_ui_mac_MacWindow 1543 * Method: _exitModal 1544 * Signature: (J)V 1545 */ 1546 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1exitModal 1547 (JNIEnv *env, jobject jWindow, jlong jPtr) 1548 { 1549 LOG("Java_com_sun_glass_ui_mac_MacWindow__1exitModal"); 1550 if (!jPtr) return; 1551 1552 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1553 GLASS_POOL_ENTER; 1554 { 1555 GlassWindow *window = getGlassWindow(env, jPtr); 1556 [NSApp stop:window->nsWindow]; 1557 } 1558 GLASS_POOL_EXIT; 1559 GLASS_CHECK_EXCEPTION(env); 1560 } 1561 1562 /* 1563 * Class: com_sun_glass_ui_mac_MacWindow 1564 * Method: _getEmbeddedX 1565 * Signature: (J)I 1566 */ 1567 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX 1568 (JNIEnv *env, jobject jWindow, jlong jPtr) 1569 { 1570 LOG("Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX"); 1571 if (!jPtr) return 0; 1572 1573 jint x = 0; 1574 1575 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1576 GLASS_POOL_ENTER; 1577 { 1578 GlassEmbeddedWindow *window = getGlassEmbeddedWindow(env, jPtr); 1579 x = (int)round([window frame].origin.x); 1580 } 1581 GLASS_POOL_EXIT; 1582 GLASS_CHECK_EXCEPTION(env); 1583 1584 return x; 1585 } 1586 1587 /* 1588 * Class: com_sun_glass_ui_mac_MacWindow 1589 * Method: _getEmbeddedY 1590 * Signature: (J)I 1591 */ 1592 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedY 1593 (JNIEnv *env, jobject jWindow, jlong jPtr) 1594 { 1595 LOG("Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedY"); 1596 if (!jPtr) return 0; 1597 1598 jint y = 0; 1599 1600 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1601 GLASS_POOL_ENTER; 1602 { 1603 GlassEmbeddedWindow *window = getGlassEmbeddedWindow(env, jPtr); 1604 NSRect frameRect = [window frame]; 1605 1606 // flip y coordinate 1607 NSScreen *screen = [[NSScreen screens] objectAtIndex:0]; 1608 NSRect screenFrame = screen.frame; 1609 y = (int)round(screenFrame.size.height - frameRect.size.height - frameRect.origin.y); 1610 } 1611 GLASS_POOL_EXIT; 1612 GLASS_CHECK_EXCEPTION(env); 1613 1614 return y; 1615 }