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 ((jStyleMask&com_sun_glass_ui_Window_POPUP) == 0 && !window->owner) 518 { 519 // Only 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 (jWindowNotifyScaleChanged == NULL) 640 { 641 jWindowNotifyScaleChanged = (*env)->GetMethodID(env, jWindowClass, "notifyScaleChanged", "(FFFF)V"); 642 if ((*env)->ExceptionCheck(env)) return; 643 } 644 645 if (jWindowNotifyClose == NULL) 646 { 647 jWindowNotifyClose = (*env)->GetMethodID(env, jWindowClass, "notifyClose", "()V"); 648 if ((*env)->ExceptionCheck(env)) return; 649 } 650 651 if (jWindowNotifyFocus == NULL) 652 { 653 jWindowNotifyFocus = (*env)->GetMethodID(env, jWindowClass, "notifyFocus", "(I)V"); 654 if ((*env)->ExceptionCheck(env)) return; 655 } 656 657 if (jWindowNotifyFocusUngrab == NULL) 658 { 659 jWindowNotifyFocusUngrab = (*env)->GetMethodID(env, jWindowClass, "notifyFocusUngrab", "()V"); 660 if ((*env)->ExceptionCheck(env)) return; 661 } 662 663 if (jWindowNotifyFocusDisabled == NULL) 664 { 665 jWindowNotifyFocusDisabled = (*env)->GetMethodID(env, jWindowClass, "notifyFocusDisabled", "()V"); 666 if ((*env)->ExceptionCheck(env)) return; 667 } 668 669 if (jWindowNotifyDestroy == NULL) 670 { 671 jWindowNotifyDestroy = (*env)->GetMethodID(env, jWindowClass, "notifyDestroy", "()V"); 672 if ((*env)->ExceptionCheck(env)) return; 673 } 674 675 if (jWindowNotifyDelegatePtr == NULL) 676 { 677 jWindowNotifyDelegatePtr = (*env)->GetMethodID(env, jWindowClass, "notifyDelegatePtr", "(J)V"); 678 } 679 } 680 681 /* 682 * Class: com_sun_glass_ui_mac_MacWindow 683 * Method: _createWindow 684 * Signature: (JJI)J 685 */ 686 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacWindow__1createWindow 687 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask) 688 { 689 LOG("Java_com_sun_glass_ui_mac_MacWindow__1createWindow"); 690 691 return _createWindowCommon(env, jWindow, jOwnerPtr, jScreenPtr, jStyleMask, JNI_FALSE); 692 } 693 694 /* 695 * Class: com_sun_glass_ui_mac_MacWindow 696 * Method: _createChildWindow 697 * Signature: (J)J 698 */ 699 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacWindow__1createChildWindow 700 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr) 701 { 702 LOG("Java_com_sun_glass_ui_mac_MacWindow__1createChildWindow"); 703 LOG(" owner: %p", jOwnerPtr); 704 705 jlong jScreenPtr = 0L; 706 jint jStyleMask = NSBorderlessWindowMask; 707 if (jOwnerPtr == BROWSER_PARENT_ID) 708 { 709 LOG(" case PARENT (PLUGIN)"); 710 // special case: embedded window for plugin (the container which will hold the child window) 711 } 712 else 713 { 714 LOG(" case CHILD (EMBEDDED)"); 715 // special case: embedded window for plugin (the actual plugin window with remote layer) 716 // jOwnerPtr must be a valid GlassEmbeddedWindow instance 717 if (![GlassEmbeddedWindow exists:(GlassEmbeddedWindow*)jlong_to_ptr(jOwnerPtr)]) { 718 return (jlong)0; 719 } 720 } 721 722 return _createWindowCommon(env, jWindow, jOwnerPtr, jScreenPtr, jStyleMask, JNI_TRUE); 723 } 724 725 /* 726 * Class: com_sun_glass_ui_mac_MacWindow 727 * Method: _setLevel 728 * Signature: (JI)V 729 */ 730 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setLevel 731 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jLevel) 732 { 733 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setLevel"); 734 if (!jPtr) return; 735 736 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 737 GLASS_POOL_ENTER; 738 { 739 GlassWindow *window = getGlassWindow(env, jPtr); 740 NSInteger level = NSNormalWindowLevel; 741 switch (jLevel) 742 { 743 case com_sun_glass_ui_Window_Level_FLOATING: 744 level = NSFloatingWindowLevel; 745 break; 746 case com_sun_glass_ui_Window_Level_TOPMOST: 747 level = NSScreenSaverWindowLevel; 748 break; 749 } 750 [window->nsWindow setLevel:level]; 751 } 752 GLASS_POOL_EXIT; 753 GLASS_CHECK_EXCEPTION(env); 754 } 755 756 /* 757 * Class: com_sun_glass_ui_mac_MacWindow 758 * Method: _setFocusable 759 * Signature: (Z)V 760 */ 761 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setFocusable 762 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean isFocusable) 763 { 764 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setCanBecomeActive"); 765 if (!jPtr) return; 766 767 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 768 GLASS_POOL_ENTER; 769 { 770 GlassWindow *window = getGlassWindow(env, jPtr); 771 window->isFocusable = (isFocusable==JNI_TRUE); 772 } 773 GLASS_POOL_EXIT; 774 GLASS_CHECK_EXCEPTION(env); 775 } 776 777 /* 778 * Class: com_sun_glass_ui_mac_MacWindow 779 * Method: _setEnabled 780 * Signature: (JZ)V 781 */ 782 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setEnabled 783 (JNIEnv *env, jobject jwindow, jlong jPtr, jboolean isEnabled) 784 { 785 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setEnabled"); 786 if (!jPtr) return; 787 788 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 789 GLASS_POOL_ENTER; 790 { 791 GlassWindow *window = getGlassWindow(env, jPtr); 792 window->isEnabled = (BOOL)isEnabled; 793 794 if (!window->isEnabled) { 795 window->enabledStyleMask = [window->nsWindow styleMask]; 796 [window->nsWindow setStyleMask: (window->enabledStyleMask & ~(NSUInteger)(NSMiniaturizableWindowMask | NSResizableWindowMask))]; 797 798 //XXX: perhaps we could simply enable/disable the buttons w/o playing with the styles at all 799 NSButton *zoomButton = [window->nsWindow standardWindowButton:NSWindowZoomButton]; 800 [zoomButton setEnabled:NO]; 801 } else { 802 [window->nsWindow setStyleMask: window->enabledStyleMask]; 803 804 if (window->enabledStyleMask & NSResizableWindowMask) { 805 NSButton *zoomButton = [window->nsWindow standardWindowButton:NSWindowZoomButton]; 806 [zoomButton setEnabled:YES]; 807 } 808 } 809 } 810 GLASS_POOL_EXIT; 811 GLASS_CHECK_EXCEPTION(env); 812 } 813 814 /* 815 * Class: com_sun_glass_ui_mac_MacWindow 816 * Method: _setAlpha 817 * Signature: (F)V 818 */ 819 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setAlpha 820 (JNIEnv *env, jobject jWindow, jlong jPtr, jfloat jAlpha) 821 { 822 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setAlpha"); 823 if (!jPtr) return; 824 825 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 826 GLASS_POOL_ENTER; 827 { 828 GlassWindow *window = getGlassWindow(env, jPtr); 829 [window->nsWindow setAlphaValue:jAlpha]; 830 } 831 GLASS_POOL_EXIT; 832 GLASS_CHECK_EXCEPTION(env); 833 } 834 835 /* 836 * Class: com_sun_glass_ui_mac_MacWindow 837 * Method: _setBackground 838 * Signature: (JFFF)Z 839 */ 840 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setBackground 841 (JNIEnv *env, jobject jWindow, jlong jPtr, jfloat r, jfloat g, jfloat b) 842 { 843 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setBackground"); 844 if (!jPtr) return JNI_FALSE; 845 846 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 847 GLASS_POOL_ENTER; 848 { 849 GlassWindow *window = getGlassWindow(env, jPtr); 850 [window->nsWindow setBackgroundColor:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0f]]; 851 } 852 GLASS_POOL_EXIT; 853 GLASS_CHECK_EXCEPTION(env); 854 855 return JNI_TRUE; // gznote: remove this return value if unused 856 } 857 858 /* 859 * Class: com_sun_glass_ui_mac_MacWindow 860 * Method: _setView 861 * Signature: (J)Z 862 */ 863 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setView 864 (JNIEnv *env, jobject jWindow, jlong jPtr, jobject jview) 865 { 866 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setView"); 867 LOG(" window: %p", jPtr); 868 LOG(" view: %p", getMacView(env, jview)); 869 if (!jPtr) return JNI_FALSE; 870 871 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 872 GLASS_POOL_ENTER; 873 { 874 GlassWindow *window = getGlassWindow(env, jPtr); 875 876 // We don't support changing views in the FS mode because 877 // by Glass design the FS functionality belongs to the View. 878 // Also, this leads to a crash on the Mac 879 if ([window->nsWindow styleMask] & (1 << 14)/*NSFullScreenWindowMask*/) { 880 [window->nsWindow performSelector:@selector(toggleFullScreen:) withObject:nil]; 881 882 // Wait until the FS mode has really exited 883 [GlassApplication enterFullScreenExitingLoop]; 884 } 885 886 NSView<GlassView> *oldView = window->view; 887 window->view = getMacView(env, jview); 888 //NSLog(@" window: %@", window); 889 //NSLog(@" frame: %.2f,%.2f %.2fx%.2f", [window frame].origin.x, [window frame].origin.y, [window frame].size.width, [window frame].size.height); 890 //NSLog(@" view: %@", window->view); 891 //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); 892 893 // Make sure we synchronize scale factors to the new view as any 894 // dynamic updates might have happened when we had the old view 895 // and/or we may have been set visible before we had a view and 896 // missed the initial notification. 897 if ([window->nsWindow screen]) { 898 [window->view notifyScaleFactorChanged:GetScreenScaleFactor([window->nsWindow screen])]; 899 } 900 901 if (oldView && oldView != window->view) { 902 [[oldView delegate] resetMouseTracking]; 903 } 904 905 if (window->view != nil) 906 { 907 CALayer *layer = [window->view layer]; 908 if (([layer isKindOfClass:[CAOpenGLLayer class]] == YES) && 909 (([window->nsWindow styleMask] & NSTexturedBackgroundWindowMask) == NO)) 910 { 911 [((CAOpenGLLayer*)layer) setOpaque:[window->nsWindow isOpaque]]; 912 } 913 914 window->suppressWindowMoveEvent = YES; // RT-11215 915 { 916 NSRect viewFrame = [window->view frame]; 917 if ((viewFrame.size.width != 0.0f) && (viewFrame.size.height != 0.0f)) 918 { 919 NSRect windowFrame = [window->nsWindow frameRectForContentRect:viewFrame]; 920 windowFrame.origin.x = [window->nsWindow frame].origin.x; 921 windowFrame.origin.y = [window->nsWindow frame].origin.y; 922 [window _setWindowFrameWithRect:NSMakeRect(windowFrame.origin.x, windowFrame.origin.y, windowFrame.size.width, windowFrame.size.height) withDisplay:JNI_TRUE withAnimate:JNI_FALSE]; 923 } 924 925 [window->nsWindow setContentView:[window->view superview]]; // use our superview not ourselves! 926 [window->nsWindow setInitialFirstResponder:window->view]; 927 [window->nsWindow makeFirstResponder:window->view]; 928 } 929 window->suppressWindowMoveEvent = NO; 930 } 931 else 932 { 933 [window->nsWindow performSelectorOnMainThread:@selector(setContentView:) withObject:nil waitUntilDone:YES]; 934 } 935 } 936 GLASS_POOL_EXIT; 937 GLASS_CHECK_EXCEPTION(env); 938 939 return JNI_TRUE; // gznote: remove this return value if unused 940 } 941 942 /* 943 * Class: com_sun_glass_ui_mac_MacWindow 944 * Method: _setMenubar 945 * Signature: (Lcom/sun/glass/ui/mac/MacMenubarDelegate;)V 946 */ 947 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMenubar 948 (JNIEnv *env, jobject jWindow, jlong jPtr, jlong jMenubarPtr) 949 { 950 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMenubar"); 951 if (!jPtr) return JNI_FALSE; 952 953 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 954 GLASS_POOL_ENTER; 955 { 956 GlassWindow *window = getGlassWindow(env, jPtr); 957 window->menubar = (GlassMenubar*)jlong_to_ptr(jMenubarPtr); 958 [NSApp setMainMenu:window->menubar->menu]; 959 [[NSApp mainMenu] update]; 960 } 961 GLASS_POOL_EXIT; 962 GLASS_CHECK_EXCEPTION(env); 963 964 return JNI_TRUE; // gznote: remove this return value if unused 965 } 966 967 /* 968 * Class: com_sun_glass_ui_mac_MacWindow 969 * Method: _close 970 * Signature: ()V 971 */ 972 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1close 973 (JNIEnv *env, jclass cls, jlong jPtr) 974 { 975 LOG("Java_com_sun_glass_ui_mac_MacWindow__1close"); 976 if (!jPtr) return JNI_FALSE; 977 978 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 979 GLASS_POOL_ENTER; 980 { 981 GlassWindow *window = getGlassWindow(env, jPtr); 982 // this call will always close the window 983 // without calling the windowShouldClose 984 985 // RT-39813 When closing a window as the result of a global right-click 986 // mouse event outside the bounds of the window, using an immediate 987 // [window->nsWindow close] crashes the JDK as the AppKit at this 988 // point still has another [NSWindow _resignKeyFocus] from the 989 // right-click handling in [NSApplication sendEvent]. This defers 990 // the close until the [NSWindow _resignKeyFocus] can be performed. 991 992 [window->nsWindow performSelectorOnMainThread:@selector(close) withObject:nil waitUntilDone:NO]; 993 994 // The NSWindow will be automatically released after closing 995 // The GlassWindow is released in the [NSWindow dealloc] override 996 } 997 GLASS_POOL_EXIT; 998 GLASS_CHECK_EXCEPTION(env); 999 1000 return JNI_TRUE; // gznote: remove this return value if unused 1001 } 1002 1003 /* 1004 * Class: com_sun_glass_ui_mac_MacWindow 1005 * Method: _requestFocus 1006 * Signature: (J)Z 1007 */ 1008 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1requestFocus 1009 (JNIEnv *env, jobject jWindow, jlong jPtr) 1010 { 1011 LOG("Java_com_sun_glass_ui_mac_MacWindow__1requestFocus"); 1012 if (!jPtr) return JNI_FALSE; 1013 1014 jboolean focused = JNI_FALSE; 1015 1016 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1017 GLASS_POOL_ENTER; 1018 { 1019 GlassWindow *window = getGlassWindow(env, jPtr); 1020 1021 if ([window->nsWindow isVisible]) 1022 { 1023 [window->nsWindow makeMainWindow]; 1024 [window->nsWindow makeKeyAndOrderFront:window->nsWindow]; 1025 [window->nsWindow orderFrontRegardless]; 1026 } 1027 1028 focused = [window->nsWindow isKeyWindow] ? JNI_TRUE : JNI_FALSE; 1029 } 1030 GLASS_POOL_EXIT; 1031 GLASS_CHECK_EXCEPTION(env); 1032 1033 return focused; 1034 } 1035 1036 /* 1037 * Class: com_sun_glass_ui_mac_MacWindow 1038 * Method: _grabFocus 1039 * Signature: (J)Z 1040 */ 1041 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1grabFocus 1042 (JNIEnv *env, jobject jThis, jlong jPtr) 1043 { 1044 LOG("Java_com_sun_glass_ui_mac_MacWindow__1grabFocus"); 1045 if (!jPtr) return JNI_FALSE; 1046 1047 jboolean ret = JNI_FALSE; 1048 1049 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1050 GLASS_POOL_ENTER; 1051 { 1052 GlassWindow * window = getGlassWindow(env, jPtr); 1053 //TODO: full screen 1054 [window _grabFocus]; 1055 ret = JNI_TRUE; 1056 } 1057 GLASS_POOL_EXIT; 1058 GLASS_CHECK_EXCEPTION(env); 1059 1060 return ret; 1061 } 1062 1063 /* 1064 * Class: com_sun_glass_ui_mac_MacWindow 1065 * Method: _ungrabFocus 1066 * Signature: (J)V 1067 */ 1068 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1ungrabFocus 1069 (JNIEnv *env, jobject jThis, jlong jPtr) 1070 { 1071 LOG("Java_com_sun_glass_ui_mac_MacWindow__1ungrabFocus"); 1072 if (!jPtr) return; 1073 1074 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1075 GLASS_POOL_ENTER; 1076 { 1077 GlassWindow * window = getGlassWindow(env, jPtr); 1078 //TODO; full screen 1079 [window _ungrabFocus]; 1080 } 1081 GLASS_POOL_EXIT; 1082 GLASS_CHECK_EXCEPTION(env); 1083 } 1084 1085 /* 1086 * Class: com_sun_glass_ui_mac_MacWindow 1087 * Method: _maximize 1088 * Signature: (JZZ)V 1089 */ 1090 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1maximize 1091 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean maximize, jboolean isZoomed) 1092 { 1093 LOG("Java_com_sun_glass_ui_mac_MacWindow__1maximize"); 1094 if (!jPtr) return JNI_FALSE; 1095 1096 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1097 GLASS_POOL_ENTER; 1098 { 1099 GlassWindow *window = getGlassWindow(env, jPtr); 1100 window->suppressWindowResizeEvent = YES; 1101 1102 if ((maximize == JNI_TRUE) && (isZoomed == JNI_FALSE)) 1103 { 1104 window->preZoomedRect = [window->nsWindow frame]; 1105 1106 if ([window->nsWindow styleMask] != NSBorderlessWindowMask) 1107 { 1108 [window->nsWindow zoom:nil]; 1109 // windowShouldZoom will be called automatically in this case 1110 } 1111 else 1112 { 1113 NSRect visibleRect = [[window _getScreen] visibleFrame]; 1114 [window _setWindowFrameWithRect:NSMakeRect(visibleRect.origin.x, visibleRect.origin.y, visibleRect.size.width, visibleRect.size.height) withDisplay:JNI_TRUE withAnimate:JNI_TRUE]; 1115 1116 // calling windowShouldZoom will send Java maximize event 1117 [window windowShouldZoom:window->nsWindow toFrame:[window->nsWindow frame]]; 1118 } 1119 } 1120 else if ((maximize == JNI_FALSE) && (isZoomed == JNI_TRUE)) 1121 { 1122 [window _restorePreZoomedRect]; 1123 } 1124 1125 window->suppressWindowResizeEvent = NO; 1126 } 1127 GLASS_POOL_EXIT; 1128 GLASS_CHECK_EXCEPTION(env); 1129 1130 return JNI_TRUE; // gznote: remove this return value if unused 1131 } 1132 1133 /* 1134 * Class: com_sun_glass_ui_mac_MacWindow 1135 * Method: _setBounds 1136 * Signature: (JIIZZIIIIFF)V 1137 */ 1138 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setBounds2 1139 (JNIEnv *env, jobject jWindow, jlong jPtr, 1140 jint x, jint y, jboolean xSet, jboolean ySet, 1141 jint w, jint h, jint cw, jint ch, jfloat xGravity, jfloat yGravity) 1142 { 1143 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setBounds"); 1144 LOG(" x,y: %d,%d", x, y); 1145 LOG(" xSet,ySet: %d,%d", xSet, ySet); 1146 LOG(" xGravity,yGravity: %.2f,%.2f", xGravity, yGravity); 1147 LOG(" w x h: %dx%d", w, h); 1148 LOG(" cw x ch: %dx%d", cw, ch); 1149 if (!jPtr) return; 1150 1151 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1152 GLASS_POOL_ENTER; 1153 { 1154 GlassWindow *window = getGlassWindow(env, jPtr); 1155 if (xSet || ySet) window->isLocationAssigned = YES; 1156 if (w > 0 || h > 0 || cw > 0 || ch > 0) window->isSizeAssigned = YES; 1157 [window _setBounds:x y:y xSet:xSet ySet:ySet w:w h:h cw:cw ch:ch]; 1158 } 1159 GLASS_POOL_EXIT; 1160 GLASS_CHECK_EXCEPTION(env); 1161 } 1162 1163 /* 1164 * Class: com_sun_glass_ui_mac_MacWindow 1165 * Method: _setMinimumSize 1166 * Signature: (JII)Z 1167 */ 1168 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMinimumSize 1169 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jW, jint jH) 1170 { 1171 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMinimumSize"); 1172 if (!jPtr) return JNI_FALSE; 1173 1174 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1175 GLASS_POOL_ENTER; 1176 { 1177 GlassWindow *window = getGlassWindow(env, jPtr); 1178 [window->nsWindow setMinSize:NSMakeSize(jW, jH)]; 1179 } 1180 GLASS_POOL_EXIT; 1181 GLASS_CHECK_EXCEPTION(env); 1182 1183 return JNI_TRUE; // gznote: remove this return value if unused 1184 } 1185 1186 /* 1187 * Class: com_sun_glass_ui_mac_MacWindow 1188 * Method: _setMaximumSize 1189 * Signature: (JII)Z 1190 */ 1191 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMaximumSize 1192 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jW, jint jH) 1193 { 1194 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMaximumSize"); 1195 if (!jPtr) return JNI_FALSE; 1196 1197 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1198 GLASS_POOL_ENTER; 1199 { 1200 GlassWindow *window = getGlassWindow(env, jPtr); 1201 [window->nsWindow setMaxSize:NSMakeSize(jW == -1 ? FLT_MAX : (CGFloat)jW, 1202 jH == -1 ? FLT_MAX : (CGFloat)jH)]; 1203 } 1204 GLASS_POOL_EXIT; 1205 GLASS_CHECK_EXCEPTION(env); 1206 1207 return JNI_TRUE; // gznote: remove this return value if unused 1208 } 1209 1210 /* 1211 * Class: com_sun_glass_ui_mac_MacWindow 1212 * Method: _setResizable 1213 * Signature: (Z)Z 1214 */ 1215 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setResizable 1216 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jResizable) 1217 { 1218 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setResizable"); 1219 if (!jPtr) return JNI_FALSE; 1220 1221 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1222 GLASS_POOL_ENTER; 1223 { 1224 GlassWindow *window = getGlassWindow(env, jPtr); 1225 if (window->isResizable != jResizable) 1226 { 1227 [window performSelectorOnMainThread:@selector(_setResizable) withObject:nil waitUntilDone:YES]; 1228 } 1229 } 1230 GLASS_POOL_EXIT; 1231 GLASS_CHECK_EXCEPTION(env); 1232 1233 return JNI_TRUE; 1234 } 1235 1236 /* 1237 * Class: com_sun_glass_ui_mac_MacWindow 1238 * Method: _setVisible 1239 * Signature: (Z)Z 1240 */ 1241 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setVisible 1242 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jVisible) 1243 { 1244 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setVisible: %d", jVisible); 1245 LOG(" window: %p", jPtr); 1246 if (!jPtr) return JNI_FALSE; 1247 1248 jboolean now = JNI_FALSE; 1249 1250 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1251 GLASS_POOL_ENTER; 1252 { 1253 GlassWindow *window = getGlassWindow(env, jPtr); 1254 if (jVisible == JNI_TRUE) 1255 { 1256 if (!window->isLocationAssigned) { 1257 [window _setBounds:0 y:0 xSet:JNI_TRUE ySet:JNI_TRUE w:-1 h:-1 cw:-1 ch:-1]; 1258 } 1259 if (!window->isSizeAssigned) { 1260 [window _setBounds:0 y:0 xSet:JNI_FALSE ySet:JNI_FALSE w:320 h:200 cw:-1 ch:-1]; 1261 } 1262 [window _setVisible]; 1263 } 1264 else 1265 { 1266 [window _ungrabFocus]; 1267 if (window->owner != nil) 1268 { 1269 LOG(" removeChildWindow: %p", window); 1270 [window->owner removeChildWindow:window->nsWindow]; 1271 } 1272 [window->nsWindow orderOut:window->nsWindow]; 1273 } 1274 now = [window->nsWindow isVisible] ? JNI_TRUE : JNI_FALSE; 1275 1276 // RT-22502 temp workaround: bring plugin window in front of a browser 1277 if (now == YES) 1278 { 1279 static BOOL isBackgroundOnlyAppChecked = NO; 1280 static BOOL isBackgroundOnlyApp = NO; 1281 if (isBackgroundOnlyAppChecked == NO) 1282 { 1283 isBackgroundOnlyAppChecked = YES; 1284 1285 ProcessSerialNumber psn; 1286 if (GetCurrentProcess(&psn) == noErr) 1287 { 1288 ProcessInfoRec info; 1289 memset(&info, 0x00, sizeof(ProcessInfoRec)); 1290 GetProcessInformation(&psn, &info); 1291 isBackgroundOnlyApp = ((modeOnlyBackground&info.processMode) == modeOnlyBackground); 1292 } 1293 } 1294 if (isBackgroundOnlyApp == YES) 1295 { 1296 [window->nsWindow performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES]; 1297 } 1298 } 1299 } 1300 GLASS_POOL_EXIT; 1301 GLASS_CHECK_EXCEPTION(env); 1302 1303 return now; 1304 } 1305 1306 /* 1307 * Class: com_sun_glass_ui_mac_MacWindow 1308 * Method: _setTitle 1309 * Signature: (Ljava/lang/String;)Z 1310 */ 1311 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setTitle 1312 (JNIEnv *env, jobject jWindow, jlong jPtr, jstring jTitle) 1313 { 1314 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setTitle"); 1315 LOG(" window: %p", jPtr); 1316 if (!jPtr) return JNI_FALSE; 1317 1318 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1319 GLASS_POOL_ENTER; 1320 { 1321 GlassWindow *window = getGlassWindow(env, jPtr); 1322 1323 NSString *title = [GlassHelper nsStringWithJavaString:jTitle withEnv:env]; 1324 LOG(" title: %s", [title UTF8String]); 1325 [window->nsWindow setTitle:title]; 1326 } 1327 GLASS_POOL_EXIT; 1328 GLASS_CHECK_EXCEPTION(env); 1329 1330 return JNI_TRUE; // gnote: remove this return value if unused 1331 } 1332 1333 /* 1334 * Class: com_sun_glass_ui_mac_MacWindow 1335 * Method: _minimize 1336 * Signature: (Z)V 1337 */ 1338 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1minimize 1339 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jMiniaturize) 1340 { 1341 LOG("Java_com_sun_glass_ui_mac_MacWindow__1minimize"); 1342 if (!jPtr) return JNI_FALSE; 1343 1344 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1345 GLASS_POOL_ENTER; 1346 { 1347 GlassWindow *window = getGlassWindow(env, jPtr); 1348 1349 if (jMiniaturize == JNI_TRUE) 1350 { 1351 [window->nsWindow miniaturize:nil]; 1352 } 1353 else 1354 { 1355 [window->nsWindow deminiaturize:nil]; 1356 } 1357 } 1358 GLASS_POOL_EXIT; 1359 GLASS_CHECK_EXCEPTION(env); 1360 1361 return JNI_TRUE; // gnote: remove this return value if unused 1362 } 1363 1364 /* 1365 * Class: com_sun_glass_ui_mac_MacWindow 1366 * Method: _setIcon 1367 * Signature: (JLcom/sun/glass/ui/Pixels;)V 1368 */ 1369 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setIcon 1370 (JNIEnv *env, jobject jWindow, jlong jPtr, jobject jPixels) 1371 { 1372 LOG("Java_com_sun_glass_ui_mac_MacWindow__1setIcon"); 1373 if (!jPtr) return; 1374 1375 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1376 GLASS_POOL_ENTER; 1377 { 1378 GlassWindow *window = getGlassWindow(env, jPtr); 1379 if (jPixels != NULL) 1380 { 1381 NSImage *image = nil; 1382 (*env)->CallVoidMethod(env, jPixels, jPixelsAttachData, ptr_to_jlong(&image)); 1383 if (image != nil) { 1384 // need an explicit window title for the rest of the code to work 1385 if ([window->nsWindow title] == nil) 1386 { 1387 [window->nsWindow setTitle:@"Untitled"]; 1388 } 1389 1390 // http://www.cocoabuilder.com/archive/cocoa/199554-nswindow-title-bar-icon-without-representedurl.html 1391 [window->nsWindow setRepresentedURL:[NSURL fileURLWithPath:[window->nsWindow title]]]; 1392 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:image]; 1393 [image release]; 1394 } else { 1395 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil]; 1396 } 1397 } else { 1398 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil]; 1399 } 1400 } 1401 GLASS_POOL_EXIT; 1402 GLASS_CHECK_EXCEPTION(env); 1403 } 1404 1405 /* 1406 * Class: com_sun_glass_ui_mac_MacWindow 1407 * Method: _toFront 1408 * Signature: (J)V 1409 */ 1410 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1toFront 1411 (JNIEnv *env, jobject jWindow, jlong jPtr) 1412 { 1413 LOG("Java_com_sun_glass_ui_mac_MacWindow__1toFront"); 1414 LOG(" window: %p", jPtr); 1415 if (!jPtr) return; 1416 1417 GLASS_POOL_ENTER; 1418 { 1419 GlassWindow *window = getGlassWindow(env, jPtr); 1420 [window->nsWindow orderFrontRegardless]; 1421 } 1422 GLASS_POOL_EXIT; 1423 GLASS_CHECK_EXCEPTION(env); 1424 } 1425 1426 /* 1427 * Class: com_sun_glass_ui_mac_MacWindow 1428 * Method: _toBack 1429 * Signature: (J)V 1430 */ 1431 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1toBack 1432 (JNIEnv *env, jobject jWindow, jlong jPtr) 1433 { 1434 LOG("Java_com_sun_glass_ui_mac_MacWindow__1toBack"); 1435 if (!jPtr) return; 1436 1437 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1438 GLASS_POOL_ENTER; 1439 { 1440 GlassWindow *window = getGlassWindow(env, jPtr); 1441 [window->nsWindow orderBack:nil]; 1442 } 1443 GLASS_POOL_EXIT; 1444 GLASS_CHECK_EXCEPTION(env); 1445 } 1446 1447 1448 /* 1449 * Class: com_sun_glass_ui_mac_MacWindow 1450 * Method: _enterModal 1451 * Signature: (J)V 1452 */ 1453 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1enterModal 1454 (JNIEnv *env, jobject jWindow, jlong jPtr) 1455 { 1456 LOG("Java_com_sun_glass_ui_mac_MacWindow__1enterModal"); 1457 if (!jPtr) return; 1458 1459 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1460 GLASS_POOL_ENTER; 1461 { 1462 GlassWindow *window = getGlassWindow(env, jPtr); 1463 [NSApp runModalForWindow:window->nsWindow]; 1464 } 1465 GLASS_POOL_EXIT; 1466 GLASS_CHECK_EXCEPTION(env); 1467 } 1468 1469 /* 1470 * Class: com_sun_glass_ui_mac_MacWindow 1471 * Method: _enterModalWithWindow 1472 * Signature: (JJ)V 1473 */ 1474 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1enterModalWithWindow 1475 (JNIEnv *env, jobject jWindow, jlong jDialogPtr, jlong jWindowPtr) 1476 { 1477 LOG("Java_com_sun_glass_ui_mac_MacWindow__1enterModalWithWindow"); 1478 1479 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1480 GLASS_POOL_ENTER; 1481 { 1482 //GlassWindow *window = getGlassWindow(env, jDialogPtr); 1483 // TODO: implement _enterModalWithWindow 1484 } 1485 GLASS_POOL_EXIT; 1486 GLASS_CHECK_EXCEPTION(env); 1487 } 1488 1489 /* 1490 * Class: com_sun_glass_ui_mac_MacWindow 1491 * Method: _exitModal 1492 * Signature: (J)V 1493 */ 1494 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1exitModal 1495 (JNIEnv *env, jobject jWindow, jlong jPtr) 1496 { 1497 LOG("Java_com_sun_glass_ui_mac_MacWindow__1exitModal"); 1498 if (!jPtr) return; 1499 1500 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1501 GLASS_POOL_ENTER; 1502 { 1503 GlassWindow *window = getGlassWindow(env, jPtr); 1504 [NSApp stop:window->nsWindow]; 1505 } 1506 GLASS_POOL_EXIT; 1507 GLASS_CHECK_EXCEPTION(env); 1508 } 1509 1510 /* 1511 * Class: com_sun_glass_ui_mac_MacWindow 1512 * Method: _getEmbeddedX 1513 * Signature: (J)I 1514 */ 1515 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX 1516 (JNIEnv *env, jobject jWindow, jlong jPtr) 1517 { 1518 LOG("Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX"); 1519 if (!jPtr) return 0; 1520 1521 jint x = 0; 1522 1523 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1524 GLASS_POOL_ENTER; 1525 { 1526 GlassEmbeddedWindow *window = getGlassEmbeddedWindow(env, jPtr); 1527 x = (int)round([window frame].origin.x); 1528 } 1529 GLASS_POOL_EXIT; 1530 GLASS_CHECK_EXCEPTION(env); 1531 1532 return x; 1533 } 1534 1535 /* 1536 * Class: com_sun_glass_ui_mac_MacWindow 1537 * Method: _getEmbeddedY 1538 * Signature: (J)I 1539 */ 1540 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedY 1541 (JNIEnv *env, jobject jWindow, jlong jPtr) 1542 { 1543 LOG("Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX"); 1544 if (!jPtr) return 0; 1545 1546 jint y = 0; 1547 1548 GLASS_ASSERT_MAIN_JAVA_THREAD(env); 1549 GLASS_POOL_ENTER; 1550 { 1551 GlassEmbeddedWindow *window = getGlassEmbeddedWindow(env, jPtr); 1552 NSRect frameRect = [window frame]; 1553 1554 // flip y coorindate 1555 NSScreen *screen = [[NSScreen screens] objectAtIndex:0]; 1556 NSRect screenFrame = screen.frame; 1557 y = (int)round(screenFrame.size.height - frameRect.size.height - frameRect.origin.y); 1558 } 1559 GLASS_POOL_EXIT; 1560 GLASS_CHECK_EXCEPTION(env); 1561 1562 return y; 1563 }