Print this page
Added gradle and cmake project
Split |
Close |
Expand all |
Collapse all |
--- old/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
+++ new/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
1 1 /*
2 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 package sun.lwawt.macosx;
27 27
28 28 import java.awt.AWTError;
29 29 import java.awt.CheckboxMenuItem;
30 30 import java.awt.Color;
31 31 import java.awt.Component;
32 32 import java.awt.Cursor;
33 33 import java.awt.Desktop;
34 34 import java.awt.Dialog;
35 35 import java.awt.Dimension;
36 36 import java.awt.Event;
37 37 import java.awt.EventQueue;
38 38 import java.awt.FileDialog;
39 39 import java.awt.Frame;
40 40 import java.awt.GraphicsConfiguration;
41 41 import java.awt.GraphicsDevice;
42 42 import java.awt.GraphicsEnvironment;
43 43 import java.awt.HeadlessException;
44 44 import java.awt.Image;
45 45 import java.awt.Insets;
46 46 import java.awt.Menu;
47 47 import java.awt.MenuBar;
48 48 import java.awt.MenuItem;
49 49 import java.awt.Point;
50 50 import java.awt.PopupMenu;
51 51 import java.awt.RenderingHints;
52 52 import java.awt.Robot;
53 53 import java.awt.SystemTray;
54 54 import java.awt.Taskbar;
55 55 import java.awt.Toolkit;
56 56 import java.awt.TrayIcon;
57 57 import java.awt.Window;
58 58 import java.awt.datatransfer.Clipboard;
59 59 import java.awt.dnd.DragGestureEvent;
60 60 import java.awt.dnd.DragGestureListener;
61 61 import java.awt.dnd.DragGestureRecognizer;
62 62 import java.awt.dnd.DragSource;
63 63 import java.awt.dnd.DropTarget;
64 64 import java.awt.dnd.InvalidDnDOperationException;
65 65 import java.awt.dnd.MouseDragGestureRecognizer;
66 66 import java.awt.dnd.peer.DragSourceContextPeer;
67 67 import java.awt.event.InputEvent;
68 68 import java.awt.event.InvocationEvent;
69 69 import java.awt.event.KeyEvent;
70 70 import java.awt.font.TextAttribute;
71 71 import java.awt.im.InputMethodHighlight;
72 72 import java.awt.im.spi.InputMethodDescriptor;
73 73 import java.awt.peer.CheckboxMenuItemPeer;
74 74 import java.awt.peer.DesktopPeer;
75 75 import java.awt.peer.DialogPeer;
76 76 import java.awt.peer.FileDialogPeer;
77 77 import java.awt.peer.FontPeer;
78 78 import java.awt.peer.MenuBarPeer;
79 79 import java.awt.peer.MenuItemPeer;
80 80 import java.awt.peer.MenuPeer;
81 81 import java.awt.peer.PopupMenuPeer;
82 82 import java.awt.peer.RobotPeer;
83 83 import java.awt.peer.SystemTrayPeer;
84 84 import java.awt.peer.TaskbarPeer;
85 85 import java.awt.peer.TrayIconPeer;
86 86 import java.lang.reflect.InvocationTargetException;
87 87 import java.lang.reflect.UndeclaredThrowableException;
88 88 import java.net.MalformedURLException;
89 89 import java.net.URL;
90 90 import java.security.AccessController;
91 91 import java.security.PrivilegedAction;
92 92 import java.util.HashMap;
93 93 import java.util.Locale;
94 94 import java.util.Map;
95 95 import java.util.MissingResourceException;
96 96 import java.util.Objects;
97 97 import java.util.ResourceBundle;
98 98 import java.util.concurrent.Callable;
99 99
100 100 import javax.swing.UIManager;
↓ open down ↓ |
100 lines elided |
↑ open up ↑ |
101 101
102 102 import com.apple.laf.AquaMenuBarUI;
103 103 import sun.awt.AWTAccessor;
104 104 import sun.awt.AppContext;
105 105 import sun.awt.CGraphicsConfig;
106 106 import sun.awt.CGraphicsDevice;
107 107 import sun.awt.LightweightFrame;
108 108 import sun.awt.SunToolkit;
109 109 import sun.awt.datatransfer.DataTransferer;
110 110 import sun.awt.util.ThreadGroupUtils;
111 +import sun.java2d.macos.MacOSFlags;
112 +import sun.java2d.metal.MTLRenderQueue;
111 113 import sun.java2d.opengl.OGLRenderQueue;
112 114 import sun.lwawt.LWComponentPeer;
113 115 import sun.lwawt.LWCursorManager;
114 116 import sun.lwawt.LWToolkit;
115 117 import sun.lwawt.LWWindowPeer;
116 118 import sun.lwawt.LWWindowPeer.PeerType;
117 119 import sun.lwawt.PlatformComponent;
118 120 import sun.lwawt.PlatformDropTarget;
119 121 import sun.lwawt.PlatformWindow;
120 122 import sun.lwawt.SecurityWarningWindow;
121 123 import sun.security.action.GetBooleanAction;
122 124
123 125 @SuppressWarnings("serial") // JDK implementation class
124 126 final class NamedCursor extends Cursor {
125 127 NamedCursor(String name) {
126 128 super(name);
127 129 }
128 130 }
129 131
130 132 /**
131 133 * Mac OS X Cocoa-based AWT Toolkit.
132 134 */
133 135 public final class LWCToolkit extends LWToolkit {
134 136 // While it is possible to enumerate all mouse devices
135 137 // and query them for the number of buttons, the code
136 138 // that does it is rather complex. Instead, we opt for
137 139 // the easy way and just support up to 5 mouse buttons,
138 140 // like Windows.
139 141 private static final int BUTTONS = 5;
140 142
141 143 private static native void initIDs();
142 144 private static native void initAppkit(ThreadGroup appKitThreadGroup, boolean headless);
143 145 private static CInputMethodDescriptor sInputMethodDescriptor;
144 146
145 147 static {
146 148 System.err.flush();
147 149
148 150 ResourceBundle platformResources = java.security.AccessController.doPrivileged(
149 151 new java.security.PrivilegedAction<ResourceBundle>() {
150 152 @Override
151 153 public ResourceBundle run() {
152 154 ResourceBundle platformResources = null;
153 155 try {
154 156 platformResources = ResourceBundle.getBundle("sun.awt.resources.awtosx");
155 157 } catch (MissingResourceException e) {
156 158 // No resource file; defaults will be used.
157 159 }
158 160
159 161 System.loadLibrary("awt");
160 162 System.loadLibrary("fontmanager");
161 163
162 164 return platformResources;
163 165 }
164 166 });
165 167
166 168 if (!GraphicsEnvironment.isHeadless() && !isInAquaSession()) {
167 169 throw new AWTError("WindowServer is not available");
168 170 }
169 171
170 172 AWTAccessor.getToolkitAccessor().setPlatformResources(platformResources);
171 173
172 174 if (!GraphicsEnvironment.isHeadless()) {
173 175 initIDs();
174 176 }
175 177 inAWT = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
176 178 @Override
177 179 public Boolean run() {
178 180 return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false"));
179 181 }
180 182 });
181 183 }
182 184
183 185 /*
184 186 * If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode
185 187 * If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode
186 188 */
187 189 private static final boolean inAWT;
188 190
189 191 public LWCToolkit() {
190 192 areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
191 193 //set system property if not yet assigned
192 194 System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
193 195 initAppkit(ThreadGroupUtils.getRootThreadGroup(), GraphicsEnvironment.isHeadless());
194 196 }
195 197
196 198 /*
197 199 * System colors with default initial values, overwritten by toolkit if system values differ and are available.
198 200 */
199 201 private static final int NUM_APPLE_COLORS = 3;
200 202 public static final int KEYBOARD_FOCUS_COLOR = 0;
201 203 public static final int INACTIVE_SELECTION_BACKGROUND_COLOR = 1;
202 204 public static final int INACTIVE_SELECTION_FOREGROUND_COLOR = 2;
203 205 private static int[] appleColors = {
204 206 0xFF808080, // keyboardFocusColor = Color.gray;
205 207 0xFFC0C0C0, // secondarySelectedControlColor
206 208 0xFF303030, // controlDarkShadowColor
207 209 };
208 210
209 211 private native void loadNativeColors(final int[] systemColors, final int[] appleColors);
210 212
211 213 @Override
212 214 protected void loadSystemColors(final int[] systemColors) {
213 215 if (systemColors == null) return;
214 216 loadNativeColors(systemColors, appleColors);
215 217 }
216 218
217 219 @SuppressWarnings("serial") // JDK implementation class
218 220 private static class AppleSpecificColor extends Color {
219 221 private final int index;
220 222 AppleSpecificColor(int index) {
221 223 super(appleColors[index]);
222 224 this.index = index;
223 225 }
224 226
225 227 @Override
226 228 public int getRGB() {
227 229 return appleColors[index];
228 230 }
229 231 }
230 232
231 233 /**
232 234 * Returns Apple specific colors that we may expose going forward.
233 235 */
234 236 public static Color getAppleColor(int color) {
235 237 return new AppleSpecificColor(color);
236 238 }
237 239
238 240 // This is only called from native code.
239 241 static void systemColorsChanged() {
240 242 EventQueue.invokeLater(() -> {
241 243 AccessController.doPrivileged( (PrivilegedAction<Object>) () -> {
242 244 AWTAccessor.getSystemColorAccessor().updateSystemColors();
243 245 return null;
244 246 });
245 247 });
246 248 }
247 249
248 250 public static LWCToolkit getLWCToolkit() {
249 251 return (LWCToolkit)Toolkit.getDefaultToolkit();
250 252 }
251 253
252 254 @Override
253 255 protected PlatformWindow createPlatformWindow(PeerType peerType) {
254 256 if (peerType == PeerType.EMBEDDED_FRAME) {
255 257 return new CPlatformEmbeddedFrame();
256 258 } else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) {
257 259 return new CViewPlatformEmbeddedFrame();
258 260 } else if (peerType == PeerType.LW_FRAME) {
259 261 return new CPlatformLWWindow();
260 262 } else {
261 263 assert (peerType == PeerType.SIMPLEWINDOW
262 264 || peerType == PeerType.DIALOG
263 265 || peerType == PeerType.FRAME);
264 266 return new CPlatformWindow();
265 267 }
266 268 }
267 269
268 270 LWWindowPeer createEmbeddedFrame(CEmbeddedFrame target) {
269 271 PlatformComponent platformComponent = createPlatformComponent();
270 272 PlatformWindow platformWindow = createPlatformWindow(PeerType.EMBEDDED_FRAME);
271 273 return createDelegatedPeer(target, platformComponent, platformWindow, PeerType.EMBEDDED_FRAME);
272 274 }
273 275
274 276 LWWindowPeer createEmbeddedFrame(CViewEmbeddedFrame target) {
275 277 PlatformComponent platformComponent = createPlatformComponent();
276 278 PlatformWindow platformWindow = createPlatformWindow(PeerType.VIEW_EMBEDDED_FRAME);
277 279 return createDelegatedPeer(target, platformComponent, platformWindow, PeerType.VIEW_EMBEDDED_FRAME);
278 280 }
279 281
280 282 private CPrinterDialogPeer createCPrinterDialog(CPrinterDialog target) {
281 283 PlatformComponent platformComponent = createPlatformComponent();
282 284 PlatformWindow platformWindow = createPlatformWindow(PeerType.DIALOG);
283 285 CPrinterDialogPeer peer = new CPrinterDialogPeer(target, platformComponent, platformWindow);
284 286 targetCreatedPeer(target, peer);
285 287 return peer;
286 288 }
287 289
288 290 @Override
289 291 public DialogPeer createDialog(Dialog target) {
290 292 if (target instanceof CPrinterDialog) {
291 293 return createCPrinterDialog((CPrinterDialog)target);
292 294 }
293 295 return super.createDialog(target);
294 296 }
295 297
296 298 @Override
297 299 protected SecurityWarningWindow createSecurityWarning(Window ownerWindow,
298 300 LWWindowPeer ownerPeer) {
299 301 return new CWarningWindow(ownerWindow, ownerPeer);
300 302 }
301 303
302 304 @Override
303 305 protected PlatformComponent createPlatformComponent() {
304 306 return new CPlatformComponent();
305 307 }
306 308
307 309 @Override
308 310 protected PlatformComponent createLwPlatformComponent() {
309 311 return new CPlatformLWComponent();
310 312 }
311 313
312 314 @Override
313 315 protected FileDialogPeer createFileDialogPeer(FileDialog target) {
314 316 return new CFileDialog(target);
315 317 }
316 318
317 319 @Override
318 320 public MenuPeer createMenu(Menu target) {
319 321 MenuPeer peer = new CMenu(target);
320 322 targetCreatedPeer(target, peer);
321 323 return peer;
322 324 }
323 325
324 326 @Override
325 327 public MenuBarPeer createMenuBar(MenuBar target) {
326 328 MenuBarPeer peer = new CMenuBar(target);
327 329 targetCreatedPeer(target, peer);
328 330 return peer;
329 331 }
330 332
331 333 @Override
332 334 public MenuItemPeer createMenuItem(MenuItem target) {
333 335 MenuItemPeer peer = new CMenuItem(target);
334 336 targetCreatedPeer(target, peer);
335 337 return peer;
336 338 }
337 339
338 340 @Override
339 341 public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) {
340 342 CheckboxMenuItemPeer peer = new CCheckboxMenuItem(target);
341 343 targetCreatedPeer(target, peer);
342 344 return peer;
343 345 }
344 346
345 347 @Override
346 348 public PopupMenuPeer createPopupMenu(PopupMenu target) {
347 349 PopupMenuPeer peer = new CPopupMenu(target);
348 350 targetCreatedPeer(target, peer);
349 351 return peer;
350 352 }
351 353
352 354 @Override
353 355 public SystemTrayPeer createSystemTray(SystemTray target) {
354 356 return new CSystemTray();
355 357 }
356 358
357 359 @Override
358 360 public TrayIconPeer createTrayIcon(TrayIcon target) {
359 361 TrayIconPeer peer = new CTrayIcon(target);
360 362 targetCreatedPeer(target, peer);
361 363 return peer;
362 364 }
363 365
364 366 @Override
365 367 public DesktopPeer createDesktopPeer(Desktop target) {
366 368 return new CDesktopPeer();
367 369 }
368 370
369 371 @Override
370 372 public TaskbarPeer createTaskbarPeer(Taskbar target) {
371 373 return new CTaskbarPeer();
372 374 }
373 375
374 376 @Override
375 377 public LWCursorManager getCursorManager() {
376 378 return CCursorManager.getInstance();
377 379 }
378 380
379 381 @Override
380 382 public Cursor createCustomCursor(final Image cursor, final Point hotSpot,
381 383 final String name)
382 384 throws IndexOutOfBoundsException, HeadlessException {
383 385 return new CCustomCursor(cursor, hotSpot, name);
384 386 }
385 387
386 388 @Override
387 389 public Dimension getBestCursorSize(final int preferredWidth,
388 390 final int preferredHeight)
389 391 throws HeadlessException {
390 392 return CCustomCursor.getBestCursorSize(preferredWidth, preferredHeight);
391 393 }
392 394
393 395 @Override
394 396 protected void platformCleanup() {
395 397 // TODO Auto-generated method stub
396 398 }
397 399
398 400 @Override
399 401 protected void platformInit() {
400 402 // TODO Auto-generated method stub
401 403 }
402 404
403 405 @Override
404 406 protected void platformRunMessage() {
405 407 // TODO Auto-generated method stub
406 408 }
407 409
408 410 @Override
409 411 protected void platformShutdown() {
410 412 // TODO Auto-generated method stub
411 413 }
412 414
413 415 class OSXPlatformFont extends sun.awt.PlatformFont
414 416 {
415 417 OSXPlatformFont(String name, int style)
416 418 {
417 419 super(name, style);
418 420 }
419 421 @Override
420 422 protected char getMissingGlyphCharacter()
421 423 {
422 424 // Follow up for real implementation
423 425 return (char)0xfff8; // see http://developer.apple.com/fonts/LastResortFont/
424 426 }
425 427 }
426 428 @Override
427 429 public FontPeer getFontPeer(String name, int style) {
428 430 return new OSXPlatformFont(name, style);
429 431 }
430 432
431 433 @Override
432 434 protected void initializeDesktopProperties() {
433 435 super.initializeDesktopProperties();
434 436 Map <Object, Object> fontHints = new HashMap<>();
435 437 fontHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
436 438 desktopProperties.put(SunToolkit.DESKTOPFONTHINTS, fontHints);
437 439 desktopProperties.put("awt.mouse.numButtons", BUTTONS);
438 440
439 441 // These DnD properties must be set, otherwise Swing ends up spewing NPEs
440 442 // all over the place. The values came straight off of MToolkit.
441 443 desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
442 444 desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50));
443 445 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5));
444 446
445 447 desktopProperties.put("DnD.isDragImageSupported", Boolean.TRUE);
446 448
447 449 // Register DnD cursors
448 450 desktopProperties.put("DnD.Cursor.CopyDrop", new NamedCursor("DnD.Cursor.CopyDrop"));
449 451 desktopProperties.put("DnD.Cursor.MoveDrop", new NamedCursor("DnD.Cursor.MoveDrop"));
450 452 desktopProperties.put("DnD.Cursor.LinkDrop", new NamedCursor("DnD.Cursor.LinkDrop"));
451 453 desktopProperties.put("DnD.Cursor.CopyNoDrop", new NamedCursor("DnD.Cursor.CopyNoDrop"));
452 454 desktopProperties.put("DnD.Cursor.MoveNoDrop", new NamedCursor("DnD.Cursor.MoveNoDrop"));
453 455 desktopProperties.put("DnD.Cursor.LinkNoDrop", new NamedCursor("DnD.Cursor.LinkNoDrop"));
454 456 }
455 457
456 458 @Override
457 459 protected boolean syncNativeQueue(long timeout) {
458 460 return nativeSyncQueue(timeout);
459 461 }
460 462
461 463 @Override
462 464 public native void beep();
463 465
464 466 @Override
465 467 public int getScreenResolution() throws HeadlessException {
466 468 return (int) ((CGraphicsDevice) GraphicsEnvironment
467 469 .getLocalGraphicsEnvironment().getDefaultScreenDevice())
468 470 .getXResolution();
↓ open down ↓ |
348 lines elided |
↑ open up ↑ |
469 471 }
470 472
471 473 @Override
472 474 public Insets getScreenInsets(final GraphicsConfiguration gc) {
473 475 return ((CGraphicsConfig) gc).getDevice().getScreenInsets();
474 476 }
475 477
476 478 @Override
477 479 public void sync() {
478 480 // flush the OGL pipeline (this is a no-op if OGL is not enabled)
479 - OGLRenderQueue.sync();
481 + if (MacOSFlags.isMetalEnabled()) {
482 + MTLRenderQueue.sync();
483 + } else {
484 + OGLRenderQueue.sync();
485 + }
480 486 // setNeedsDisplay() selector was sent to the appropriate CALayer so now
481 487 // we have to flush the native selectors queue.
482 488 flushNativeSelectors();
483 489 }
484 490
485 491 @Override
486 492 public RobotPeer createRobot(Robot target, GraphicsDevice screen) {
487 493 return new CRobot(target, (CGraphicsDevice)screen);
488 494 }
489 495
490 496 private native boolean isCapsLockOn();
491 497
492 498 /*
493 499 * NOTE: Among the keys this method is supposed to check,
494 500 * only Caps Lock works as a true locking key with OS X.
495 501 * There is no Scroll Lock key on modern Apple keyboards,
496 502 * and with a PC keyboard plugged in Scroll Lock is simply
497 503 * ignored: no LED lights up if you press it.
498 504 * The key located at the same position on Apple keyboards
499 505 * as Num Lock on PC keyboards is called Clear, doesn't lock
500 506 * anything and is used for entirely different purpose.
501 507 */
502 508 @Override
503 509 public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
504 510 switch (keyCode) {
505 511 case KeyEvent.VK_NUM_LOCK:
506 512 case KeyEvent.VK_SCROLL_LOCK:
507 513 case KeyEvent.VK_KANA_LOCK:
508 514 throw new UnsupportedOperationException("Toolkit.getLockingKeyState");
509 515
510 516 case KeyEvent.VK_CAPS_LOCK:
511 517 return isCapsLockOn();
512 518
513 519 default:
514 520 throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
515 521 }
516 522 }
517 523
518 524 //Is it allowed to generate events assigned to extra mouse buttons.
519 525 //Set to true by default.
520 526 private static boolean areExtraMouseButtonsEnabled = true;
521 527
522 528 @Override
523 529 public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
524 530 return areExtraMouseButtonsEnabled;
525 531 }
526 532
527 533 @Override
528 534 public int getNumberOfButtons(){
529 535 return BUTTONS;
530 536 }
531 537
532 538 @Override
533 539 public boolean isTraySupported() {
534 540 return true;
535 541 }
536 542
537 543 @Override
538 544 public DataTransferer getDataTransferer() {
539 545 return CDataTransferer.getInstanceImpl();
540 546 }
541 547
542 548 @Override
543 549 public boolean isAlwaysOnTopSupported() {
544 550 return true;
545 551 }
546 552
547 553 private static final String APPKIT_THREAD_NAME = "AppKit Thread";
548 554
549 555 // Intended to be called from the LWCToolkit.m only.
550 556 private static void installToolkitThreadInJava() {
551 557 Thread.currentThread().setName(APPKIT_THREAD_NAME);
552 558 AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
553 559 Thread.currentThread().setContextClassLoader(null);
554 560 return null;
555 561 });
556 562 }
557 563
558 564 @Override
559 565 public boolean isWindowOpacitySupported() {
560 566 return true;
561 567 }
562 568
563 569 @Override
564 570 public boolean isFrameStateSupported(int state) throws HeadlessException {
565 571 switch (state) {
566 572 case Frame.NORMAL:
567 573 case Frame.ICONIFIED:
568 574 case Frame.MAXIMIZED_BOTH:
569 575 return true;
570 576 default:
571 577 return false;
572 578 }
573 579 }
574 580
575 581 @Override
576 582 @Deprecated(since = "10")
577 583 public int getMenuShortcutKeyMask() {
578 584 return Event.META_MASK;
579 585 }
580 586
581 587 @Override
582 588 public int getMenuShortcutKeyMaskEx() {
583 589 return InputEvent.META_DOWN_MASK;
584 590 }
585 591
586 592 @Override
587 593 public Image getImage(final String filename) {
588 594 final Image nsImage = checkForNSImage(filename);
589 595 if (nsImage != null) {
590 596 return nsImage;
591 597 }
592 598
593 599 if (imageCached(filename)) {
594 600 return super.getImage(filename);
595 601 }
596 602
597 603 String filename2x = getScaledImageName(filename);
598 604 return (imageExists(filename2x))
599 605 ? getImageWithResolutionVariant(filename, filename2x)
600 606 : super.getImage(filename);
601 607 }
602 608
603 609 @Override
604 610 public Image getImage(URL url) {
605 611
606 612 if (imageCached(url)) {
607 613 return super.getImage(url);
608 614 }
609 615
610 616 URL url2x = getScaledImageURL(url);
611 617 return (imageExists(url2x))
612 618 ? getImageWithResolutionVariant(url, url2x) : super.getImage(url);
613 619 }
614 620
615 621 private static final String nsImagePrefix = "NSImage://";
616 622 private Image checkForNSImage(final String imageName) {
617 623 if (imageName == null) return null;
618 624 if (!imageName.startsWith(nsImagePrefix)) return null;
619 625 return CImage.getCreator().createImageFromName(imageName.substring(nsImagePrefix.length()));
620 626 }
621 627
622 628 // Thread-safe Object.equals() called from native
623 629 public static boolean doEquals(final Object a, final Object b, Component c) {
624 630 if (a == b) return true;
625 631
626 632 final boolean[] ret = new boolean[1];
627 633
628 634 try { invokeAndWait(new Runnable() { @Override
629 635 public void run() { synchronized(ret) {
630 636 ret[0] = a.equals(b);
631 637 }}}, c); } catch (Exception e) { e.printStackTrace(); }
632 638
633 639 synchronized(ret) { return ret[0]; }
634 640 }
635 641
636 642 public static <T> T invokeAndWait(final Callable<T> callable,
637 643 Component component) throws Exception {
638 644 final CallableWrapper<T> wrapper = new CallableWrapper<>(callable);
639 645 invokeAndWait(wrapper, component);
640 646 return wrapper.getResult();
641 647 }
642 648
643 649 static final class CallableWrapper<T> implements Runnable {
644 650 final Callable<T> callable;
645 651 T object;
646 652 Exception e;
647 653
648 654 CallableWrapper(final Callable<T> callable) {
649 655 this.callable = callable;
650 656 }
651 657
652 658 @Override
653 659 public void run() {
654 660 try {
655 661 object = callable.call();
656 662 } catch (final Exception e) {
657 663 this.e = e;
658 664 }
659 665 }
660 666
661 667 public T getResult() throws Exception {
662 668 if (e != null) throw e;
663 669 return object;
664 670 }
665 671 }
666 672
667 673 /**
668 674 * Kicks an event over to the appropriate event queue and waits for it to
669 675 * finish To avoid deadlocking, we manually run the NSRunLoop while waiting
670 676 * Any selector invoked using ThreadUtilities performOnMainThread will be
671 677 * processed in doAWTRunLoop The InvocationEvent will call
672 678 * LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual
673 679 * run loop. Does not dispatch native events while in the loop
674 680 */
675 681 public static void invokeAndWait(Runnable runnable, Component component)
676 682 throws InvocationTargetException {
677 683 Objects.requireNonNull(component, "Null component provided to invokeAndWait");
678 684
679 685 long mediator = createAWTRunLoopMediator();
680 686 InvocationEvent invocationEvent =
681 687 new InvocationEvent(component,
682 688 runnable,
683 689 () -> {
684 690 if (mediator != 0) {
685 691 stopAWTRunLoop(mediator);
686 692 }
687 693 },
688 694 true);
689 695
690 696 AppContext appContext = SunToolkit.targetToAppContext(component);
691 697 SunToolkit.postEvent(appContext, invocationEvent);
692 698 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
693 699 SunToolkit.flushPendingEvents(appContext);
694 700 doAWTRunLoop(mediator, false);
695 701
696 702 checkException(invocationEvent);
697 703 }
698 704
699 705 public static void invokeLater(Runnable event, Component component)
700 706 throws InvocationTargetException {
701 707 Objects.requireNonNull(component, "Null component provided to invokeLater");
702 708
703 709 InvocationEvent invocationEvent = new InvocationEvent(component, event);
704 710
705 711 AppContext appContext = SunToolkit.targetToAppContext(component);
706 712 SunToolkit.postEvent(SunToolkit.targetToAppContext(component), invocationEvent);
707 713 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock
708 714 SunToolkit.flushPendingEvents(appContext);
709 715
710 716 checkException(invocationEvent);
711 717 }
712 718
713 719 /**
714 720 * Checks if exception occurred while {@code InvocationEvent} was processed and rethrows it as
715 721 * an {@code InvocationTargetException}
716 722 *
717 723 * @param event the event to check for an exception
718 724 * @throws InvocationTargetException if exception occurred when event was processed
719 725 */
720 726 private static void checkException(InvocationEvent event) throws InvocationTargetException {
721 727 Throwable eventException = event.getException();
722 728 if (eventException == null) return;
723 729
724 730 if (eventException instanceof UndeclaredThrowableException) {
725 731 eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable();
726 732 }
727 733 throw new InvocationTargetException(eventException);
728 734 }
729 735
730 736 /**
731 737 * Schedules a {@code Runnable} execution on the Appkit thread after a delay
732 738 * @param r a {@code Runnable} to execute
733 739 * @param delay a delay in milliseconds
734 740 */
735 741 static native void performOnMainThreadAfterDelay(Runnable r, long delay);
736 742
737 743 // DnD support
738 744
739 745 @Override
740 746 public DragSourceContextPeer createDragSourceContextPeer(
741 747 DragGestureEvent dge) throws InvalidDnDOperationException {
742 748 final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
743 749 if (f != null) {
744 750 return f.createDragSourceContextPeer(dge);
745 751 }
746 752
747 753 return CDragSourceContextPeer.createDragSourceContextPeer(dge);
748 754 }
749 755
750 756 @Override
751 757 @SuppressWarnings("unchecked")
752 758 public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
753 759 Class<T> abstractRecognizerClass, DragSource ds, Component c,
754 760 int srcActions, DragGestureListener dgl) {
755 761 final LightweightFrame f = SunToolkit.getLightweightFrame(c);
756 762 if (f != null) {
757 763 return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl);
758 764 }
759 765
760 766 DragGestureRecognizer dgr = null;
761 767
762 768 // Create a new mouse drag gesture recognizer if we have a class match:
763 769 if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
764 770 dgr = new CMouseDragGestureRecognizer(ds, c, srcActions, dgl);
765 771
766 772 return (T)dgr;
767 773 }
768 774
769 775 @Override
770 776 protected PlatformDropTarget createDropTarget(DropTarget dropTarget,
771 777 Component component,
772 778 LWComponentPeer<?, ?> peer) {
773 779 return new CDropTarget(dropTarget, component, peer);
774 780 }
775 781
776 782 // InputMethodSupport Method
777 783 /**
778 784 * Returns the default keyboard locale of the underlying operating system
779 785 */
780 786 @Override
781 787 public Locale getDefaultKeyboardLocale() {
782 788 Locale locale = CInputMethod.getNativeLocale();
783 789
784 790 if (locale == null) {
785 791 return super.getDefaultKeyboardLocale();
786 792 }
787 793
788 794 return locale;
789 795 }
790 796
791 797 @Override
792 798 public InputMethodDescriptor getInputMethodAdapterDescriptor() {
793 799 if (sInputMethodDescriptor == null)
794 800 sInputMethodDescriptor = new CInputMethodDescriptor();
795 801
796 802 return sInputMethodDescriptor;
797 803 }
798 804
799 805 /**
800 806 * Returns a map of visual attributes for thelevel description
801 807 * of the given input method highlight, or null if no mapping is found.
802 808 * The style field of the input method highlight is ignored. The map
803 809 * returned is unmodifiable.
804 810 * @param highlight input method highlight
805 811 * @return style attribute map, or null
806 812 * @since 1.3
807 813 */
808 814 @Override
809 815 public Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) {
810 816 return CInputMethod.mapInputMethodHighlight(highlight);
811 817 }
812 818
813 819 /**
814 820 * Returns key modifiers used by Swing to set up a focus accelerator key
815 821 * stroke.
816 822 */
817 823 @Override
818 824 @SuppressWarnings("deprecation")
819 825 public int getFocusAcceleratorKeyMask() {
820 826 return InputEvent.CTRL_MASK | InputEvent.ALT_MASK;
821 827 }
822 828
823 829 /**
824 830 * Tests whether specified key modifiers mask can be used to enter a
825 831 * printable character.
826 832 */
827 833 @Override
828 834 @SuppressWarnings("deprecation")
829 835 public boolean isPrintableCharacterModifiersMask(int mods) {
830 836 return ((mods & (InputEvent.META_MASK | InputEvent.CTRL_MASK)) == 0);
831 837 }
832 838
833 839 /**
834 840 * Returns whether popup is allowed to be shown above the task bar.
835 841 */
836 842 @Override
837 843 public boolean canPopupOverlapTaskBar() {
838 844 return false;
839 845 }
840 846
841 847 private static Boolean sunAwtDisableCALayers = null;
842 848
843 849 /**
844 850 * Returns the value of "sun.awt.disableCALayers" property. Default
845 851 * value is {@code false}.
846 852 */
847 853 public static synchronized boolean getSunAwtDisableCALayers() {
848 854 if (sunAwtDisableCALayers == null) {
849 855 sunAwtDisableCALayers = AccessController.doPrivileged(
850 856 new GetBooleanAction("sun.awt.disableCALayers"));
851 857 }
852 858 return sunAwtDisableCALayers;
853 859 }
854 860
855 861 /*
856 862 * Returns true if the application (one of its windows) owns keyboard focus.
857 863 */
858 864 native boolean isApplicationActive();
859 865
860 866 /**
861 867 * Returns true if AWT toolkit is embedded, false otherwise.
862 868 *
863 869 * @return true if AWT toolkit is embedded, false otherwise
864 870 */
865 871 public static native boolean isEmbedded();
866 872
867 873 /**
868 874 * Returns true if the WindowServer is available, false otherwise.
869 875 *
870 876 * @return true if the WindowServer is available, false otherwise
871 877 */
872 878 private static native boolean isInAquaSession();
873 879
874 880 /*
875 881 * Activates application ignoring other apps.
876 882 */
877 883 public native void activateApplicationIgnoringOtherApps();
878 884
879 885 /************************
880 886 * Native methods section
881 887 ************************/
882 888
883 889 static native long createAWTRunLoopMediator();
884 890 /**
885 891 * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent
886 892 * by [JNFRunLoop performOnMainThreadWaiting] are processed.
887 893 * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator
888 894 * @param processEvents if true - dispatches event while in the nested loop. Used in DnD.
889 895 * Additional attention is needed when using this feature as we short-circuit normal event
890 896 * processing which could break Appkit.
891 897 * (One known example is when the window is resized with the mouse)
892 898 *
893 899 * if false - all events come after exit form the nested loop
894 900 */
895 901 static void doAWTRunLoop(long mediator, boolean processEvents) {
896 902 doAWTRunLoopImpl(mediator, processEvents, inAWT);
897 903 }
898 904 private static native void doAWTRunLoopImpl(long mediator, boolean processEvents, boolean inAWT);
899 905 static native void stopAWTRunLoop(long mediator);
900 906
901 907 private native boolean nativeSyncQueue(long timeout);
902 908
903 909 /**
904 910 * Just spin a single empty block synchronously.
905 911 */
906 912 static native void flushNativeSelectors();
907 913
908 914 @Override
909 915 public Clipboard createPlatformClipboard() {
910 916 return new CClipboard("System");
911 917 }
912 918
913 919 @Override
914 920 public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
915 921 return (exclusionType == null) ||
916 922 (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) ||
917 923 (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) ||
918 924 (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
919 925 }
920 926
921 927 @Override
922 928 public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
923 929 //TODO: FileDialog blocks excluded windows...
924 930 //TODO: Test: 2 file dialogs, separate AppContexts: a) Dialog 1 blocked, shouldn't be. Frame 4 blocked (shouldn't be).
925 931 return (modalityType == null) ||
926 932 (modalityType == Dialog.ModalityType.MODELESS) ||
927 933 (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
928 934 (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
929 935 (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
930 936 }
931 937
932 938 @Override
933 939 public boolean isWindowShapingSupported() {
934 940 return true;
935 941 }
936 942
937 943 @Override
938 944 public boolean isWindowTranslucencySupported() {
939 945 return true;
940 946 }
941 947
942 948 @Override
943 949 public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
944 950 return true;
945 951 }
946 952
947 953 @Override
948 954 public boolean isSwingBackbufferTranslucencySupported() {
949 955 return true;
950 956 }
951 957
952 958 @Override
953 959 public boolean enableInputMethodsForTextComponent() {
954 960 return true;
955 961 }
956 962
957 963 private static URL getScaledImageURL(URL url) {
958 964 try {
959 965 String scaledImagePath = getScaledImageName(url.getPath());
960 966 return scaledImagePath == null ? null : new URL(url.getProtocol(),
961 967 url.getHost(), url.getPort(), scaledImagePath);
962 968 } catch (MalformedURLException e) {
963 969 return null;
964 970 }
965 971 }
966 972
967 973 private static String getScaledImageName(String path) {
968 974 if (!isValidPath(path)) {
969 975 return null;
970 976 }
971 977
972 978 int slash = path.lastIndexOf('/');
973 979 String name = (slash < 0) ? path : path.substring(slash + 1);
974 980
975 981 if (name.contains("@2x")) {
976 982 return null;
977 983 }
978 984
979 985 int dot = name.lastIndexOf('.');
980 986 String name2x = (dot < 0) ? name + "@2x"
981 987 : name.substring(0, dot) + "@2x" + name.substring(dot);
982 988 return (slash < 0) ? name2x : path.substring(0, slash + 1) + name2x;
983 989 }
984 990
985 991 private static boolean isValidPath(String path) {
986 992 return path != null &&
987 993 !path.isEmpty() &&
988 994 !path.endsWith("/") &&
989 995 !path.endsWith(".");
990 996 }
991 997
992 998 @Override
993 999 protected PlatformWindow getPlatformWindowUnderMouse() {
994 1000 return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();
995 1001 }
996 1002
997 1003 @Override
998 1004 public void updateScreenMenuBarUI() {
999 1005 if (AquaMenuBarUI.getScreenMenuBarProperty()) {
1000 1006 UIManager.put("MenuBarUI", "com.apple.laf.AquaMenuBarUI");
1001 1007 } else {
1002 1008 UIManager.put("MenuBarUI", null);
1003 1009 }
1004 1010 }
1005 1011 }
↓ open down ↓ |
516 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX