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