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