185 }} 186 }) { 187 public CPlatformWindow convertJComponentToTarget(final JRootPane p) { 188 Component root = SwingUtilities.getRoot(p); 189 if (root == null || (LWWindowPeer)root.getPeer() == null) return null; 190 return (CPlatformWindow)((LWWindowPeer)root.getPeer()).getPlatformWindow(); 191 } 192 }; 193 194 // Bounds of the native widget but in the Java coordinate system. 195 // In order to keep it up-to-date we will update them on 196 // 1) setting native bounds via nativeSetBounds() call 197 // 2) getting notification from the native level via deliverMoveResizeEvent() 198 private Rectangle nativeBounds; 199 private volatile boolean isFullScreenMode = false; 200 201 private Window target; 202 private LWWindowPeer peer; 203 private CPlatformView contentView; 204 private CPlatformWindow owner; 205 206 public CPlatformWindow(final PeerType peerType) { 207 super(0, true); 208 assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME); 209 } 210 211 /* 212 * Delegate initialization (create native window and all the 213 * related resources). 214 */ 215 @Override // PlatformWindow 216 public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) { 217 this.peer = _peer; 218 this.target = _target; 219 if (_owner instanceof CPlatformWindow) { 220 this.owner = (CPlatformWindow)_owner; 221 } 222 223 final int styleBits = getInitialStyleBits(); 224 260 } 261 262 protected int getInitialStyleBits() { 263 // defaults style bits 264 int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE; 265 266 if (isNativelyFocusableWindow()) { 267 styleBits = SET(styleBits, SHOULD_BECOME_KEY, true); 268 styleBits = SET(styleBits, SHOULD_BECOME_MAIN, true); 269 } 270 271 final boolean isFrame = (target instanceof Frame); 272 final boolean isDialog = (target instanceof Dialog); 273 final boolean isPopup = (target.getType() == Window.Type.POPUP); 274 if (isDialog) { 275 styleBits = SET(styleBits, MINIMIZABLE, false); 276 } 277 278 // Either java.awt.Frame or java.awt.Dialog can be undecorated, however java.awt.Window always is undecorated. 279 { 280 final boolean undecorated = isFrame ? ((Frame)target).isUndecorated() : (isDialog ? ((Dialog)target).isUndecorated() : true); 281 if (undecorated) styleBits = SET(styleBits, DECORATED, false); 282 } 283 284 // Either java.awt.Frame or java.awt.Dialog can be resizable, however java.awt.Window is never resizable 285 { 286 final boolean resizable = isFrame ? ((Frame)target).isResizable() : (isDialog ? ((Dialog)target).isResizable() : false); 287 styleBits = SET(styleBits, RESIZABLE, resizable); 288 if (!resizable) { 289 styleBits = SET(styleBits, RESIZABLE, false); 290 styleBits = SET(styleBits, ZOOMABLE, false); 291 } 292 } 293 294 if (target.isAlwaysOnTop()) { 295 styleBits = SET(styleBits, ALWAYS_ON_TOP, true); 296 } 297 298 if (target.getModalExclusionType() == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) { 299 styleBits = SET(styleBits, MODAL_EXCLUDED, true); 300 } 301 449 return nativeGetScreenNSWindowIsOn_AppKitThread(getNSWindowPtr()); 450 } 451 452 @Override // PlatformWindow 453 public SurfaceData getScreenSurface() { 454 // TODO: not implemented 455 return null; 456 } 457 458 @Override // PlatformWindow 459 public SurfaceData replaceSurfaceData() { 460 return contentView.replaceSurfaceData(); 461 } 462 463 @Override // PlatformWindow 464 public void setBounds(int x, int y, int w, int h) { 465 // assert CThreading.assertEventQueue(); 466 nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h); 467 } 468 469 @Override // PlatformWindow 470 public void setVisible(boolean visible) { 471 final long nsWindowPtr = getNSWindowPtr(); 472 473 if (owner != null) { 474 if (!visible) { 475 CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr); 476 } 477 } 478 479 updateIconImages(); 480 updateFocusabilityForAutoRequestFocus(false); 481 482 if (!visible) { 483 // Cancel out the current native state of the window 484 switch (peer.getState()) { 485 case Frame.ICONIFIED: 486 CWrapper.NSWindow.deminiaturize(nsWindowPtr); 487 break; 488 case Frame.MAXIMIZED_BOTH: 489 CWrapper.NSWindow.zoom(nsWindowPtr); 490 break; 491 } 492 } 493 494 LWWindowPeer blocker = peer.getBlocker(); 495 if (blocker == null || !visible) { 496 // If it ain't blocked, or is being hidden, go regular way 497 if (visible) { 498 CWrapper.NSWindow.makeFirstResponder(nsWindowPtr, contentView.getAWTView()); 499 500 boolean isPopup = (target.getType() == Window.Type.POPUP); 501 if (isPopup) { 502 // Popups in applets don't activate applet's process 503 CWrapper.NSWindow.orderFrontRegardless(nsWindowPtr); 504 } else { 505 CWrapper.NSWindow.orderFront(nsWindowPtr); 506 } 507 508 boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(nsWindowPtr); 509 if (!isKeyWindow) { 510 CWrapper.NSWindow.makeKeyWindow(nsWindowPtr); 511 } 512 } else { 513 CWrapper.NSWindow.orderOut(nsWindowPtr); 514 } 515 } else { 516 // otherwise, put it in a proper z-order 517 CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowBelow, 518 ((CPlatformWindow)blocker.getPlatformWindow()).getNSWindowPtr()); 519 } 520 521 if (visible) { 522 // Re-apply the extended state as expected in shared code 523 if (target instanceof Frame) { 524 switch (((Frame)target).getExtendedState()) { 525 case Frame.ICONIFIED: 526 CWrapper.NSWindow.miniaturize(nsWindowPtr); 527 break; 528 case Frame.MAXIMIZED_BOTH: 529 CWrapper.NSWindow.zoom(nsWindowPtr); 530 break; 531 } 532 } 533 } 534 535 updateFocusabilityForAutoRequestFocus(true); 536 537 if (owner != null) { 538 if (visible) { 539 CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove); 540 if (target.isAlwaysOnTop()) { 541 CWrapper.NSWindow.setLevel(nsWindowPtr, CWrapper.NSWindow.NSFloatingWindowLevel); 542 } 543 } 544 } 545 546 if (blocker != null && visible) { 547 // Make sure the blocker is above its siblings 548 ((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings(); 549 } 675 contentView.exitFullScreenMode(); 676 isFullScreenMode = false; 677 } 678 679 @Override 680 public void setWindowState(int windowState) { 681 if (!peer.isVisible()) { 682 // setVisible() applies the state 683 return; 684 } 685 686 int prevWindowState = peer.getState(); 687 if (prevWindowState == windowState) return; 688 689 final long nsWindowPtr = getNSWindowPtr(); 690 switch (windowState) { 691 case Frame.ICONIFIED: 692 if (prevWindowState == Frame.MAXIMIZED_BOTH) { 693 // let's return into the normal states first 694 // the zoom call toggles between the normal and the max states 695 CWrapper.NSWindow.zoom(nsWindowPtr); 696 } 697 CWrapper.NSWindow.miniaturize(nsWindowPtr); 698 break; 699 case Frame.MAXIMIZED_BOTH: 700 if (prevWindowState == Frame.ICONIFIED) { 701 // let's return into the normal states first 702 CWrapper.NSWindow.deminiaturize(nsWindowPtr); 703 } 704 CWrapper.NSWindow.zoom(nsWindowPtr); 705 break; 706 case Frame.NORMAL: 707 if (prevWindowState == Frame.ICONIFIED) { 708 CWrapper.NSWindow.deminiaturize(nsWindowPtr); 709 } else if (prevWindowState == Frame.MAXIMIZED_BOTH) { 710 // the zoom call toggles between the normal and the max states 711 CWrapper.NSWindow.zoom(nsWindowPtr); 712 } 713 break; 714 default: 715 throw new RuntimeException("Unknown window state: " + windowState); 716 } 717 718 // NOTE: the SWP.windowState field gets updated to the newWindowState 719 // value when the native notification comes to us 720 } 721 722 // ---------------------------------------------------------------------- 723 // UTILITY METHODS 724 // ---------------------------------------------------------------------- 725 726 /* 727 * Find image to install into Title or into Application icon. 728 * First try icons installed for toplevel. If there is no icon 729 * use default Duke image. 730 * This method shouldn't return null. 731 */ | 185 }} 186 }) { 187 public CPlatformWindow convertJComponentToTarget(final JRootPane p) { 188 Component root = SwingUtilities.getRoot(p); 189 if (root == null || (LWWindowPeer)root.getPeer() == null) return null; 190 return (CPlatformWindow)((LWWindowPeer)root.getPeer()).getPlatformWindow(); 191 } 192 }; 193 194 // Bounds of the native widget but in the Java coordinate system. 195 // In order to keep it up-to-date we will update them on 196 // 1) setting native bounds via nativeSetBounds() call 197 // 2) getting notification from the native level via deliverMoveResizeEvent() 198 private Rectangle nativeBounds; 199 private volatile boolean isFullScreenMode = false; 200 201 private Window target; 202 private LWWindowPeer peer; 203 private CPlatformView contentView; 204 private CPlatformWindow owner; 205 private boolean undecorated; // initialized in getInitialStyleBits() 206 private Rectangle normalBounds = null; // not-null only for undecorated maximized windows 207 208 public CPlatformWindow(final PeerType peerType) { 209 super(0, true); 210 assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME); 211 } 212 213 /* 214 * Delegate initialization (create native window and all the 215 * related resources). 216 */ 217 @Override // PlatformWindow 218 public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) { 219 this.peer = _peer; 220 this.target = _target; 221 if (_owner instanceof CPlatformWindow) { 222 this.owner = (CPlatformWindow)_owner; 223 } 224 225 final int styleBits = getInitialStyleBits(); 226 262 } 263 264 protected int getInitialStyleBits() { 265 // defaults style bits 266 int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE; 267 268 if (isNativelyFocusableWindow()) { 269 styleBits = SET(styleBits, SHOULD_BECOME_KEY, true); 270 styleBits = SET(styleBits, SHOULD_BECOME_MAIN, true); 271 } 272 273 final boolean isFrame = (target instanceof Frame); 274 final boolean isDialog = (target instanceof Dialog); 275 final boolean isPopup = (target.getType() == Window.Type.POPUP); 276 if (isDialog) { 277 styleBits = SET(styleBits, MINIMIZABLE, false); 278 } 279 280 // Either java.awt.Frame or java.awt.Dialog can be undecorated, however java.awt.Window always is undecorated. 281 { 282 this.undecorated = isFrame ? ((Frame)target).isUndecorated() : (isDialog ? ((Dialog)target).isUndecorated() : true); 283 if (this.undecorated) styleBits = SET(styleBits, DECORATED, false); 284 } 285 286 // Either java.awt.Frame or java.awt.Dialog can be resizable, however java.awt.Window is never resizable 287 { 288 final boolean resizable = isFrame ? ((Frame)target).isResizable() : (isDialog ? ((Dialog)target).isResizable() : false); 289 styleBits = SET(styleBits, RESIZABLE, resizable); 290 if (!resizable) { 291 styleBits = SET(styleBits, RESIZABLE, false); 292 styleBits = SET(styleBits, ZOOMABLE, false); 293 } 294 } 295 296 if (target.isAlwaysOnTop()) { 297 styleBits = SET(styleBits, ALWAYS_ON_TOP, true); 298 } 299 300 if (target.getModalExclusionType() == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) { 301 styleBits = SET(styleBits, MODAL_EXCLUDED, true); 302 } 303 451 return nativeGetScreenNSWindowIsOn_AppKitThread(getNSWindowPtr()); 452 } 453 454 @Override // PlatformWindow 455 public SurfaceData getScreenSurface() { 456 // TODO: not implemented 457 return null; 458 } 459 460 @Override // PlatformWindow 461 public SurfaceData replaceSurfaceData() { 462 return contentView.replaceSurfaceData(); 463 } 464 465 @Override // PlatformWindow 466 public void setBounds(int x, int y, int w, int h) { 467 // assert CThreading.assertEventQueue(); 468 nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h); 469 } 470 471 private void zoom() { 472 if (!undecorated) { 473 CWrapper.NSWindow.zoom(getNSWindowPtr()); 474 } else { 475 // OS X handles -zoom incorrectly for undecorated windows 476 final boolean isZoomed = this.normalBounds == null; 477 deliverZoom(isZoomed); 478 479 Rectangle toBounds; 480 if (isZoomed) { 481 this.normalBounds = peer.getBounds(); 482 long screen = CWrapper.NSWindow.screen(getNSWindowPtr()); 483 toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds(); 484 // Flip the y coordinate 485 Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds(); 486 toBounds.y = frame.height - toBounds.y - toBounds.height; 487 } else { 488 toBounds = normalBounds; 489 this.normalBounds = null; 490 } 491 setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height); 492 } 493 } 494 495 @Override // PlatformWindow 496 public void setVisible(boolean visible) { 497 final long nsWindowPtr = getNSWindowPtr(); 498 499 if (owner != null) { 500 if (!visible) { 501 CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr); 502 } 503 } 504 505 updateIconImages(); 506 updateFocusabilityForAutoRequestFocus(false); 507 508 if (!visible) { 509 // Cancel out the current native state of the window 510 switch (peer.getState()) { 511 case Frame.ICONIFIED: 512 CWrapper.NSWindow.deminiaturize(nsWindowPtr); 513 break; 514 case Frame.MAXIMIZED_BOTH: 515 zoom(); 516 break; 517 } 518 } 519 520 LWWindowPeer blocker = peer.getBlocker(); 521 if (blocker == null || !visible) { 522 // If it ain't blocked, or is being hidden, go regular way 523 if (visible) { 524 CWrapper.NSWindow.makeFirstResponder(nsWindowPtr, contentView.getAWTView()); 525 526 boolean isPopup = (target.getType() == Window.Type.POPUP); 527 if (isPopup) { 528 // Popups in applets don't activate applet's process 529 CWrapper.NSWindow.orderFrontRegardless(nsWindowPtr); 530 } else { 531 CWrapper.NSWindow.orderFront(nsWindowPtr); 532 } 533 534 boolean isKeyWindow = CWrapper.NSWindow.isKeyWindow(nsWindowPtr); 535 if (!isKeyWindow) { 536 CWrapper.NSWindow.makeKeyWindow(nsWindowPtr); 537 } 538 } else { 539 CWrapper.NSWindow.orderOut(nsWindowPtr); 540 } 541 } else { 542 // otherwise, put it in a proper z-order 543 CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowBelow, 544 ((CPlatformWindow)blocker.getPlatformWindow()).getNSWindowPtr()); 545 } 546 547 if (visible) { 548 // Re-apply the extended state as expected in shared code 549 if (target instanceof Frame) { 550 switch (((Frame)target).getExtendedState()) { 551 case Frame.ICONIFIED: 552 CWrapper.NSWindow.miniaturize(nsWindowPtr); 553 break; 554 case Frame.MAXIMIZED_BOTH: 555 zoom(); 556 break; 557 } 558 } 559 } 560 561 updateFocusabilityForAutoRequestFocus(true); 562 563 if (owner != null) { 564 if (visible) { 565 CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove); 566 if (target.isAlwaysOnTop()) { 567 CWrapper.NSWindow.setLevel(nsWindowPtr, CWrapper.NSWindow.NSFloatingWindowLevel); 568 } 569 } 570 } 571 572 if (blocker != null && visible) { 573 // Make sure the blocker is above its siblings 574 ((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings(); 575 } 701 contentView.exitFullScreenMode(); 702 isFullScreenMode = false; 703 } 704 705 @Override 706 public void setWindowState(int windowState) { 707 if (!peer.isVisible()) { 708 // setVisible() applies the state 709 return; 710 } 711 712 int prevWindowState = peer.getState(); 713 if (prevWindowState == windowState) return; 714 715 final long nsWindowPtr = getNSWindowPtr(); 716 switch (windowState) { 717 case Frame.ICONIFIED: 718 if (prevWindowState == Frame.MAXIMIZED_BOTH) { 719 // let's return into the normal states first 720 // the zoom call toggles between the normal and the max states 721 zoom(); 722 } 723 CWrapper.NSWindow.miniaturize(nsWindowPtr); 724 break; 725 case Frame.MAXIMIZED_BOTH: 726 if (prevWindowState == Frame.ICONIFIED) { 727 // let's return into the normal states first 728 CWrapper.NSWindow.deminiaturize(nsWindowPtr); 729 } 730 zoom(); 731 break; 732 case Frame.NORMAL: 733 if (prevWindowState == Frame.ICONIFIED) { 734 CWrapper.NSWindow.deminiaturize(nsWindowPtr); 735 } else if (prevWindowState == Frame.MAXIMIZED_BOTH) { 736 // the zoom call toggles between the normal and the max states 737 zoom(); 738 } 739 break; 740 default: 741 throw new RuntimeException("Unknown window state: " + windowState); 742 } 743 744 // NOTE: the SWP.windowState field gets updated to the newWindowState 745 // value when the native notification comes to us 746 } 747 748 // ---------------------------------------------------------------------- 749 // UTILITY METHODS 750 // ---------------------------------------------------------------------- 751 752 /* 753 * Find image to install into Title or into Application icon. 754 * First try icons installed for toplevel. If there is no icon 755 * use default Duke image. 756 * This method shouldn't return null. 757 */ |