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