1 /* 2 * Copyright (c) 2011, 2013, 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 package sun.lwawt.macosx; 27 28 import java.awt.*; 29 import java.awt.datatransfer.Clipboard; 30 import java.awt.dnd.*; 31 import java.awt.dnd.peer.DragSourceContextPeer; 32 import java.awt.event.InputEvent; 33 import java.awt.event.InvocationEvent; 34 import java.awt.event.KeyEvent; 35 import java.awt.im.InputMethodHighlight; 36 import java.awt.peer.*; 37 import java.lang.reflect.*; 38 import java.security.*; 39 import java.util.*; 40 import java.util.concurrent.Callable; 41 42 import sun.awt.*; 43 import sun.lwawt.*; 44 import sun.lwawt.LWWindowPeer.PeerType; 45 import sun.security.action.GetBooleanAction; 46 47 import sun.util.CoreResourceBundleControl; 48 49 class NamedCursor extends Cursor { 50 NamedCursor(String name) { 51 super(name); 52 } 53 } 54 55 /** 56 * Mac OS X Cocoa-based AWT Toolkit. 57 */ 58 public final class LWCToolkit extends LWToolkit { 59 // While it is possible to enumerate all mouse devices 60 // and query them for the number of buttons, the code 61 // that does it is rather complex. Instead, we opt for 62 // the easy way and just support up to 5 mouse buttons, 63 // like Windows. 64 private static final int BUTTONS = 5; 65 66 private static native void initIDs(); 67 68 private static CInputMethodDescriptor sInputMethodDescriptor; 69 70 static { 71 System.err.flush(); 72 73 ResourceBundle platformResources = java.security.AccessController.doPrivileged( 74 new java.security.PrivilegedAction<ResourceBundle>() { 75 public ResourceBundle run() { 76 ResourceBundle platformResources = null; 77 try { 78 platformResources = 79 ResourceBundle.getBundle("sun.awt.resources.awtosx", 80 CoreResourceBundleControl.getRBControlInstance()); 81 } catch (MissingResourceException e) { 82 // No resource file; defaults will be used. 83 } 84 85 System.loadLibrary("awt"); 86 System.loadLibrary("fontmanager"); 87 88 return platformResources; 89 } 90 }); 91 92 AWTAccessor.getToolkitAccessor().setPlatformResources(platformResources); 93 94 if (!GraphicsEnvironment.isHeadless()) { 95 initIDs(); 96 } 97 inAWT = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 98 @Override 99 public Boolean run() { 100 return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false")); 101 } 102 }); 103 } 104 105 /* 106 * If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode 107 * If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode 108 */ 109 private static final boolean inAWT; 110 111 public LWCToolkit() { 112 SunToolkit.setDataTransfererClassName("sun.lwawt.macosx.CDataTransferer"); 113 114 areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true")); 115 //set system property if not yet assigned 116 System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled); 117 } 118 119 /* 120 * System colors with default initial values, overwritten by toolkit if system values differ and are available. 121 */ 122 private final static int NUM_APPLE_COLORS = 3; 123 public final static int KEYBOARD_FOCUS_COLOR = 0; 124 public final static int INACTIVE_SELECTION_BACKGROUND_COLOR = 1; 125 public final static int INACTIVE_SELECTION_FOREGROUND_COLOR = 2; 126 private static int[] appleColors = { 127 0xFF808080, // keyboardFocusColor = Color.gray; 128 0xFFC0C0C0, // secondarySelectedControlColor 129 0xFF303030, // controlDarkShadowColor 130 }; 131 132 private native void loadNativeColors(final int[] systemColors, final int[] appleColors); 133 134 protected void loadSystemColors(final int[] systemColors) { 135 if (systemColors == null) return; 136 loadNativeColors(systemColors, appleColors); 137 } 138 139 private static class AppleSpecificColor extends Color { 140 int index; 141 public AppleSpecificColor(int index) { 142 super(appleColors[index]); 143 this.index = index; 144 } 145 146 public int getRGB() { 147 return appleColors[index]; 148 } 149 } 150 151 /** 152 * Returns Apple specific colors that we may expose going forward. 153 * 154 */ 155 public static Color getAppleColor(int color) { 156 return new AppleSpecificColor(color); 157 } 158 159 static void systemColorsChanged() { 160 // This is only called from native code. 161 EventQueue.invokeLater(new Runnable() { 162 public void run() { 163 AccessController.doPrivileged (new PrivilegedAction<Object>() { 164 public Object run() { 165 try { 166 final Method updateColorsMethod = SystemColor.class.getDeclaredMethod("updateSystemColors", new Class[0]); 167 updateColorsMethod.setAccessible(true); 168 updateColorsMethod.invoke(null, new Object[0]); 169 } catch (final Throwable e) { 170 e.printStackTrace(); 171 // swallow this if something goes horribly wrong 172 } 173 return null; 174 } 175 }); 176 } 177 }); 178 } 179 180 public static LWCToolkit getLWCToolkit() { 181 return (LWCToolkit)Toolkit.getDefaultToolkit(); 182 } 183 184 @Override 185 protected PlatformWindow createPlatformWindow(PeerType peerType) { 186 if (peerType == PeerType.EMBEDDED_FRAME) { 187 return new CPlatformEmbeddedFrame(); 188 } else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) { 189 return new CViewPlatformEmbeddedFrame(); 190 } else if (peerType == PeerType.LW_FRAME) { 191 return new CPlatformLWWindow(); 192 } else { 193 assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME); 194 return new CPlatformWindow(); 195 } 196 } 197 198 @Override 199 protected SecurityWarningWindow createSecurityWarning(Window ownerWindow, LWWindowPeer ownerPeer) { 200 return new CWarningWindow(ownerWindow, ownerPeer); 201 } 202 203 @Override 204 protected PlatformComponent createPlatformComponent() { 205 return new CPlatformComponent(); 206 } 207 208 @Override 209 protected PlatformComponent createLwPlatformComponent() { 210 return new CPlatformLWComponent(); 211 } 212 213 @Override 214 protected FileDialogPeer createFileDialogPeer(FileDialog target) { 215 return new CFileDialog(target); 216 } 217 218 @Override 219 public MenuPeer createMenu(Menu target) { 220 MenuPeer peer = new CMenu(target); 221 targetCreatedPeer(target, peer); 222 return peer; 223 } 224 225 @Override 226 public MenuBarPeer createMenuBar(MenuBar target) { 227 MenuBarPeer peer = new CMenuBar(target); 228 targetCreatedPeer(target, peer); 229 return peer; 230 } 231 232 @Override 233 public MenuItemPeer createMenuItem(MenuItem target) { 234 MenuItemPeer peer = new CMenuItem(target); 235 targetCreatedPeer(target, peer); 236 return peer; 237 } 238 239 @Override 240 public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) { 241 CheckboxMenuItemPeer peer = new CCheckboxMenuItem(target); 242 targetCreatedPeer(target, peer); 243 return peer; 244 } 245 246 @Override 247 public PopupMenuPeer createPopupMenu(PopupMenu target) { 248 PopupMenuPeer peer = new CPopupMenu(target); 249 targetCreatedPeer(target, peer); 250 return peer; 251 252 } 253 254 @Override 255 public SystemTrayPeer createSystemTray(SystemTray target) { 256 SystemTrayPeer peer = new CSystemTray(); 257 return peer; 258 } 259 260 @Override 261 public TrayIconPeer createTrayIcon(TrayIcon target) { 262 TrayIconPeer peer = new CTrayIcon(target); 263 targetCreatedPeer(target, peer); 264 return peer; 265 } 266 267 @Override 268 public LWCursorManager getCursorManager() { 269 return CCursorManager.getInstance(); 270 } 271 272 @Override 273 public Cursor createCustomCursor(final Image cursor, final Point hotSpot, final String name) throws IndexOutOfBoundsException, HeadlessException { 274 return new CCustomCursor(cursor, hotSpot, name); 275 } 276 277 @Override 278 public Dimension getBestCursorSize(final int preferredWidth, final int preferredHeight) throws HeadlessException { 279 return CCustomCursor.getBestCursorSize(preferredWidth, preferredHeight); 280 } 281 282 @Override 283 protected void platformCleanup() { 284 // TODO Auto-generated method stub 285 286 } 287 288 @Override 289 protected void platformInit() { 290 // TODO Auto-generated method stub 291 292 } 293 294 @Override 295 protected void platformRunMessage() { 296 // TODO Auto-generated method stub 297 298 } 299 300 @Override 301 protected void platformShutdown() { 302 // TODO Auto-generated method stub 303 304 } 305 306 class OSXPlatformFont extends sun.awt.PlatformFont 307 { 308 public OSXPlatformFont(String name, int style) 309 { 310 super(name, style); 311 } 312 protected char getMissingGlyphCharacter() 313 { 314 // Follow up for real implementation 315 return (char)0xfff8; // see http://developer.apple.com/fonts/LastResortFont/ 316 } 317 } 318 public FontPeer getFontPeer(String name, int style) { 319 return new OSXPlatformFont(name, style); 320 } 321 322 @Override 323 protected MouseInfoPeer createMouseInfoPeerImpl() { 324 return new CMouseInfoPeer(); 325 } 326 327 @Override 328 protected int getScreenHeight() { 329 return GraphicsEnvironment.getLocalGraphicsEnvironment() 330 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height; 331 } 332 333 @Override 334 protected int getScreenWidth() { 335 return GraphicsEnvironment.getLocalGraphicsEnvironment() 336 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().width; 337 } 338 339 @Override 340 protected void initializeDesktopProperties() { 341 super.initializeDesktopProperties(); 342 Map <Object, Object> fontHints = new HashMap<Object, Object>(); 343 fontHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 344 fontHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 345 desktopProperties.put(SunToolkit.DESKTOPFONTHINTS, fontHints); 346 desktopProperties.put("awt.mouse.numButtons", BUTTONS); 347 348 // These DnD properties must be set, otherwise Swing ends up spewing NPEs 349 // all over the place. The values came straight off of MToolkit. 350 desktopProperties.put("DnD.Autoscroll.initialDelay", new Integer(50)); 351 desktopProperties.put("DnD.Autoscroll.interval", new Integer(50)); 352 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", new Integer(5)); 353 354 desktopProperties.put("DnD.isDragImageSupported", new Boolean(true)); 355 356 // Register DnD cursors 357 desktopProperties.put("DnD.Cursor.CopyDrop", new NamedCursor("DnD.Cursor.CopyDrop")); 358 desktopProperties.put("DnD.Cursor.MoveDrop", new NamedCursor("DnD.Cursor.MoveDrop")); 359 desktopProperties.put("DnD.Cursor.LinkDrop", new NamedCursor("DnD.Cursor.LinkDrop")); 360 desktopProperties.put("DnD.Cursor.CopyNoDrop", new NamedCursor("DnD.Cursor.CopyNoDrop")); 361 desktopProperties.put("DnD.Cursor.MoveNoDrop", new NamedCursor("DnD.Cursor.MoveNoDrop")); 362 desktopProperties.put("DnD.Cursor.LinkNoDrop", new NamedCursor("DnD.Cursor.LinkNoDrop")); 363 364 } 365 366 367 /* 368 * The method returns true if some events were processed during that timeout. 369 * @see sun.awt.SunToolkit#syncNativeQueue(long) 370 */ 371 @Override 372 protected boolean syncNativeQueue(long timeout) { 373 return nativeSyncQueue(timeout); 374 } 375 376 @Override 377 public native void beep(); 378 379 @Override 380 public int getScreenResolution() throws HeadlessException { 381 return (int) ((CGraphicsDevice) GraphicsEnvironment 382 .getLocalGraphicsEnvironment().getDefaultScreenDevice()) 383 .getXResolution(); 384 } 385 386 @Override 387 public Insets getScreenInsets(final GraphicsConfiguration gc) { 388 return ((CGraphicsConfig) gc).getDevice().getScreenInsets(); 389 } 390 391 @Override 392 public void sync() { 393 // TODO Auto-generated method stub 394 395 } 396 397 @Override 398 public RobotPeer createRobot(Robot target, GraphicsDevice screen) { 399 return new CRobot(target, (CGraphicsDevice)screen); 400 } 401 402 private native boolean isCapsLockOn(); 403 404 /* 405 * NOTE: Among the keys this method is supposed to check, 406 * only Caps Lock works as a true locking key with OS X. 407 * There is no Scroll Lock key on modern Apple keyboards, 408 * and with a PC keyboard plugged in Scroll Lock is simply 409 * ignored: no LED lights up if you press it. 410 * The key located at the same position on Apple keyboards 411 * as Num Lock on PC keyboards is called Clear, doesn't lock 412 * anything and is used for entirely different purpose. 413 */ 414 public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException { 415 switch (keyCode) { 416 case KeyEvent.VK_NUM_LOCK: 417 case KeyEvent.VK_SCROLL_LOCK: 418 case KeyEvent.VK_KANA_LOCK: 419 throw new UnsupportedOperationException("Toolkit.getLockingKeyState"); 420 421 case KeyEvent.VK_CAPS_LOCK: 422 return isCapsLockOn(); 423 424 default: 425 throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState"); 426 } 427 } 428 429 //Is it allowed to generate events assigned to extra mouse buttons. 430 //Set to true by default. 431 private static boolean areExtraMouseButtonsEnabled = true; 432 433 public boolean areExtraMouseButtonsEnabled() throws HeadlessException { 434 return areExtraMouseButtonsEnabled; 435 } 436 437 public int getNumberOfButtons(){ 438 return BUTTONS; 439 } 440 441 @Override 442 public boolean isTraySupported() { 443 return true; 444 } 445 446 @Override 447 public boolean isAlwaysOnTopSupported() { 448 return true; 449 } 450 451 // Intended to be called from the LWCToolkit.m only. 452 private static void installToolkitThreadNameInJava() { 453 Thread.currentThread().setName(CThreading.APPKIT_THREAD_NAME); 454 } 455 456 @Override 457 public boolean isWindowOpacitySupported() { 458 return true; 459 } 460 461 @Override 462 public boolean isFrameStateSupported(int state) throws HeadlessException { 463 switch (state) { 464 case Frame.NORMAL: 465 case Frame.ICONIFIED: 466 case Frame.MAXIMIZED_BOTH: 467 return true; 468 default: 469 return false; 470 } 471 } 472 473 /** 474 * Determines which modifier key is the appropriate accelerator 475 * key for menu shortcuts. 476 * <p> 477 * Menu shortcuts, which are embodied in the 478 * <code>MenuShortcut</code> class, are handled by the 479 * <code>MenuBar</code> class. 480 * <p> 481 * By default, this method returns <code>Event.CTRL_MASK</code>. 482 * Toolkit implementations should override this method if the 483 * <b>Control</b> key isn't the correct key for accelerators. 484 * @return the modifier mask on the <code>Event</code> class 485 * that is used for menu shortcuts on this toolkit. 486 * @see java.awt.MenuBar 487 * @see java.awt.MenuShortcut 488 * @since JDK1.1 489 */ 490 public int getMenuShortcutKeyMask() { 491 return Event.META_MASK; 492 } 493 494 @Override 495 public Image getImage(final String filename) { 496 final Image nsImage = checkForNSImage(filename); 497 if (nsImage != null) return nsImage; 498 499 return super.getImage(filename); 500 } 501 502 static final String nsImagePrefix = "NSImage://"; 503 protected Image checkForNSImage(final String imageName) { 504 if (imageName == null) return null; 505 if (!imageName.startsWith(nsImagePrefix)) return null; 506 return CImage.getCreator().createImageFromName(imageName.substring(nsImagePrefix.length())); 507 } 508 509 // Thread-safe Object.equals() called from native 510 public static boolean doEquals(final Object a, final Object b, Component c) { 511 if (a == b) return true; 512 513 final boolean[] ret = new boolean[1]; 514 515 try { invokeAndWait(new Runnable() { public void run() { synchronized(ret) { 516 ret[0] = a.equals(b); 517 }}}, c); } catch (Exception e) { e.printStackTrace(); } 518 519 synchronized(ret) { return ret[0]; } 520 } 521 522 public static <T> T invokeAndWait(final Callable<T> callable, Component component) throws Exception { 523 final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable); 524 invokeAndWait(wrapper, component); 525 return wrapper.getResult(); 526 } 527 528 static final class CallableWrapper<T> implements Runnable { 529 final Callable<T> callable; 530 T object; 531 Exception e; 532 533 public CallableWrapper(final Callable<T> callable) { 534 this.callable = callable; 535 } 536 537 public void run() { 538 try { 539 object = callable.call(); 540 } catch (final Exception e) { 541 this.e = e; 542 } 543 } 544 545 public T getResult() throws Exception { 546 if (e != null) throw e; 547 return object; 548 } 549 } 550 551 // Kicks an event over to the appropriate eventqueue and waits for it to finish 552 // To avoid deadlocking, we manually run the NSRunLoop while waiting 553 // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop 554 // The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop 555 // Does not dispatch native events while in the loop 556 public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException { 557 final long mediator = createAWTRunLoopMediator(); 558 559 InvocationEvent invocationEvent = 560 new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event) { 561 @Override 562 public void dispatch() { 563 try { 564 super.dispatch(); 565 } finally { 566 if (mediator != 0) { 567 stopAWTRunLoop(mediator); 568 } 569 } 570 } 571 }; 572 573 if (component != null) { 574 AppContext appContext = SunToolkit.targetToAppContext(component); 575 SunToolkit.postEvent(appContext, invocationEvent); 576 577 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock 578 SunToolkit.flushPendingEvents(appContext); 579 } else { 580 // This should be the equivalent to EventQueue.invokeAndWait 581 ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); 582 } 583 584 doAWTRunLoop(mediator, false); 585 586 Throwable eventException = invocationEvent.getException(); 587 if (eventException != null) { 588 if (eventException instanceof UndeclaredThrowableException) { 589 eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable(); 590 } 591 throw new InvocationTargetException(eventException); 592 } 593 } 594 595 public static void invokeLater(Runnable event, Component component) throws InvocationTargetException { 596 final InvocationEvent invocationEvent = 597 new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event); 598 599 if (component != null) { 600 final AppContext appContext = SunToolkit.targetToAppContext(component); 601 SunToolkit.postEvent(appContext, invocationEvent); 602 603 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock 604 SunToolkit.flushPendingEvents(appContext); 605 } else { 606 // This should be the equivalent to EventQueue.invokeAndWait 607 ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); 608 } 609 610 final Throwable eventException = invocationEvent.getException(); 611 if (eventException == null) return; 612 613 if (eventException instanceof UndeclaredThrowableException) { 614 throw new InvocationTargetException(((UndeclaredThrowableException)eventException).getUndeclaredThrowable()); 615 } 616 throw new InvocationTargetException(eventException); 617 } 618 619 // This exists purely to get around permissions issues with getSystemEventQueueImpl 620 EventQueue getSystemEventQueueForInvokeAndWait() { 621 return getSystemEventQueueImpl(); 622 } 623 624 625 // DnD support 626 627 public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException { 628 DragSourceContextPeer dscp = CDragSourceContextPeer.createDragSourceContextPeer(dge); 629 630 return dscp; 631 } 632 633 public <T extends DragGestureRecognizer> T createDragGestureRecognizer(Class<T> abstractRecognizerClass, DragSource ds, Component c, int srcActions, DragGestureListener dgl) { 634 DragGestureRecognizer dgr = null; 635 636 // Create a new mouse drag gesture recognizer if we have a class match: 637 if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass)) 638 dgr = new CMouseDragGestureRecognizer(ds, c, srcActions, dgl); 639 640 return (T)dgr; 641 } 642 643 // InputMethodSupport Method 644 /** 645 * Returns the default keyboard locale of the underlying operating system 646 */ 647 public Locale getDefaultKeyboardLocale() { 648 Locale locale = CInputMethod.getNativeLocale(); 649 650 if (locale == null) { 651 return super.getDefaultKeyboardLocale(); 652 } 653 654 return locale; 655 } 656 657 public java.awt.im.spi.InputMethodDescriptor getInputMethodAdapterDescriptor() { 658 if (sInputMethodDescriptor == null) 659 sInputMethodDescriptor = new CInputMethodDescriptor(); 660 661 return sInputMethodDescriptor; 662 } 663 664 /** 665 * Returns a map of visual attributes for thelevel description 666 * of the given input method highlight, or null if no mapping is found. 667 * The style field of the input method highlight is ignored. The map 668 * returned is unmodifiable. 669 * @param highlight input method highlight 670 * @return style attribute map, or null 671 * @since 1.3 672 */ 673 public Map mapInputMethodHighlight(InputMethodHighlight highlight) { 674 return CInputMethod.mapInputMethodHighlight(highlight); 675 } 676 677 /** 678 * Returns key modifiers used by Swing to set up a focus accelerator key stroke. 679 */ 680 @Override 681 public int getFocusAcceleratorKeyMask() { 682 return InputEvent.CTRL_MASK | InputEvent.ALT_MASK; 683 } 684 685 /** 686 * Tests whether specified key modifiers mask can be used to enter a printable 687 * character. 688 */ 689 @Override 690 public boolean isPrintableCharacterModifiersMask(int mods) { 691 return ((mods & (InputEvent.META_MASK | InputEvent.CTRL_MASK)) == 0); 692 } 693 694 /** 695 * Returns whether popup is allowed to be shown above the task bar. 696 */ 697 @Override 698 public boolean canPopupOverlapTaskBar() { 699 return false; 700 } 701 702 private static Boolean sunAwtDisableCALayers = null; 703 704 /** 705 * Returns the value of "sun.awt.disableCALayers" property. Default 706 * value is {@code false}. 707 */ 708 public synchronized static boolean getSunAwtDisableCALayers() { 709 if (sunAwtDisableCALayers == null) { 710 sunAwtDisableCALayers = AccessController.doPrivileged( 711 new GetBooleanAction("sun.awt.disableCALayers")); 712 } 713 return sunAwtDisableCALayers.booleanValue(); 714 } 715 716 717 /* 718 * Returns true if the application (one of its windows) owns keyboard focus. 719 */ 720 public native boolean isApplicationActive(); 721 722 /************************ 723 * Native methods section 724 ************************/ 725 726 static native long createAWTRunLoopMediator(); 727 /** 728 * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent 729 * by [JNFRunLoop performOnMainThreadWaiting] are processed. 730 * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator 731 * @param processEvents if true - dispatches event while in the nested loop. Used in DnD. 732 * Additional attention is needed when using this feature as we short-circuit normal event 733 * processing which could break Appkit. 734 * (One known example is when the window is resized with the mouse) 735 * 736 * if false - all events come after exit form the nested loop 737 */ 738 static void doAWTRunLoop(long mediator, boolean processEvents) { 739 doAWTRunLoopImpl(mediator, processEvents, inAWT); 740 } 741 static private native void doAWTRunLoopImpl(long mediator, boolean processEvents, boolean inAWT); 742 static native void stopAWTRunLoop(long mediator); 743 744 private native boolean nativeSyncQueue(long timeout); 745 746 @Override 747 public Clipboard createPlatformClipboard() { 748 return new CClipboard("System"); 749 } 750 751 @Override 752 public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) { 753 return (exclusionType == null) || 754 (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) || 755 (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) || 756 (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); 757 } 758 759 @Override 760 public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) { 761 //TODO: FileDialog blocks excluded windows... 762 //TODO: Test: 2 file dialogs, separate AppContexts: a) Dialog 1 blocked, shouldn't be. Frame 4 blocked (shouldn't be). 763 return (modalityType == null) || 764 (modalityType == Dialog.ModalityType.MODELESS) || 765 (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) || 766 (modalityType == Dialog.ModalityType.APPLICATION_MODAL) || 767 (modalityType == Dialog.ModalityType.TOOLKIT_MODAL); 768 } 769 770 @Override 771 public boolean isWindowShapingSupported() { 772 return true; 773 } 774 775 @Override 776 public boolean isWindowTranslucencySupported() { 777 return true; 778 } 779 780 @Override 781 public boolean isTranslucencyCapable(GraphicsConfiguration gc) { 782 return true; 783 } 784 785 public boolean isSwingBackbufferTranslucencySupported() { 786 return true; 787 } 788 789 @Override 790 public boolean enableInputMethodsForTextComponent() { 791 return true; 792 } 793 }