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