source: josm/trunk/src/org/openstreetmap/josm/tools/PlatformHookOsx.java@ 13450

Last change on this file since 13450 was 13450, checked in by Don-vip, 6 years ago

fix #15992 - load native certificates from macOS system root trust store, see https://support.apple.com/en-us/HT208127

  • Property svn:eol-style set to native
File size: 36.6 KB
RevLine 
[6380]1// License: GPL. For details, see LICENSE file.
[1023]2package org.openstreetmap.josm.tools;
3
[4998]4import static org.openstreetmap.josm.tools.I18n.tr;
5
[10178]6import java.awt.Desktop;
[7485]7import java.awt.Image;
[7482]8import java.awt.Window;
[1023]9import java.awt.event.KeyEvent;
[13450]10import java.io.ByteArrayInputStream;
[7253]11import java.io.File;
[1023]12import java.io.IOException;
[1634]13import java.lang.reflect.InvocationHandler;
[10178]14import java.lang.reflect.InvocationTargetException;
[1634]15import java.lang.reflect.Method;
16import java.lang.reflect.Proxy;
[13450]17import java.nio.charset.StandardCharsets;
18import java.security.KeyStoreException;
19import java.security.NoSuchAlgorithmException;
20import java.security.cert.CertificateException;
21import java.security.cert.CertificateFactory;
22import java.security.cert.X509Certificate;
[7287]23import java.util.Arrays;
[7253]24import java.util.List;
[12695]25import java.util.Objects;
[13450]26import java.util.concurrent.ExecutionException;
[1634]27
[1023]28import javax.swing.UIManager;
29
[1634]30import org.openstreetmap.josm.Main;
[13450]31import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
[1634]32
[1023]33/**
[6443]34 * {@code PlatformHook} implementation for Apple Mac OS X systems.
35 * @since 1023
[1842]36 */
[11156]37public class PlatformHookOsx implements PlatformHook, InvocationHandler {
[6851]38
[12217]39 private String oSBuildNumber;
40
[12695]41 private NativeOsCallback osCallback;
42
[1842]43 @Override
[12776]44 public Platform getPlatform() {
45 return Platform.OSX;
46 }
47
48 @Override
[6443]49 public void preStartupHook() {
[1169]50 // This will merge our MenuBar into the system menu.
51 // MUST be set before Swing is initialized!
[6443]52 // And will not work when one of the system independent LAFs is used.
[1169]53 // They just insist on painting themselves...
[7894]54 Utils.updateSystemProperty("apple.laf.useScreenMenuBar", "true");
[12123]55 Utils.updateSystemProperty("apple.awt.application.name", "JOSM");
[1169]56 }
[6851]57
[1842]58 @Override
[12670]59 public void startupHook(JavaExpirationCallback callback) {
[7287]60 // Here we register callbacks for the menu entries in the system menu and file opening through double-click
[10178]61 // http://openjdk.java.net/jeps/272
62 // https://bugs.openjdk.java.net/browse/JDK-8048731
63 // http://cr.openjdk.java.net/~azvegint/jdk/9/8143227/10/jdk/
64 // This method must be cleaned up after we switch to Java 9
[1169]65 try {
[7482]66 Class<?> eawtApplication = Class.forName("com.apple.eawt.Application");
[10178]67 Class<?> quitHandler = findHandlerClass("QuitHandler");
68 Class<?> aboutHandler = findHandlerClass("AboutHandler");
69 Class<?> openFilesHandler = findHandlerClass("OpenFilesHandler");
70 Class<?> preferencesHandler = findHandlerClass("PreferencesHandler");
[7482]71 Object proxy = Proxy.newProxyInstance(PlatformHookOsx.class.getClassLoader(), new Class<?>[] {
[12697]72 quitHandler, aboutHandler, openFilesHandler, preferencesHandler}, this);
[12268]73 Object appli = eawtApplication.getConstructor((Class[]) null).newInstance((Object[]) null);
74 if (Utils.getJavaVersion() >= 9) {
75 setHandlers(Desktop.class, quitHandler, aboutHandler, openFilesHandler, preferencesHandler, proxy, Desktop.getDesktop());
76 } else {
[10178]77 setHandlers(eawtApplication, quitHandler, aboutHandler, openFilesHandler, preferencesHandler, proxy, appli);
[12268]78 // this method has been deprecated, but without replacement. To remove with Java 9 migration
[10178]79 eawtApplication.getDeclaredMethod("setEnabledPreferencesMenu", boolean.class).invoke(appli, Boolean.TRUE);
80 }
[12268]81 // setup the dock icon. It is automatically set with application bundle and Web start but we need
82 // to do it manually if run with `java -jar``
83 eawtApplication.getDeclaredMethod("setDockIconImage", Image.class).invoke(appli, ImageProvider.get("logo").getImage());
84 // enable full screen
85 enableOSXFullscreen((Window) Main.parent);
[7253]86 } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException ex) {
[6248]87 // We'll just ignore this for now. The user will still be able to close JOSM by closing all its windows.
[12620]88 Logging.warn("Failed to register with OSX: " + ex);
[1169]89 }
[12670]90 checkExpiredJava(callback);
[1169]91 }
[6851]92
[12748]93 @Override
94 public int getMenuShortcutKeyMaskEx() {
95 return KeyEvent.META_DOWN_MASK;
96 }
97
[12123]98 /**
99 * Registers Apple handlers.
100 * @param appClass application class
101 * @param quitHandler quit handler class
102 * @param aboutHandler about handler class
103 * @param openFilesHandler open file handler class
104 * @param preferencesHandler preferences handler class
105 * @param proxy proxy
106 * @param appInstance application instance (instance of {@code appClass})
107 * @throws IllegalAccessException in case of reflection error
108 * @throws InvocationTargetException in case of reflection error
109 * @throws NoSuchMethodException if any {@code set*Handler} method cannot be found
110 */
[10178]111 protected void setHandlers(Class<?> appClass, Class<?> quitHandler, Class<?> aboutHandler,
112 Class<?> openFilesHandler, Class<?> preferencesHandler, Object proxy, Object appInstance)
113 throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
114 appClass.getDeclaredMethod("setQuitHandler", quitHandler).invoke(appInstance, proxy);
115 appClass.getDeclaredMethod("setAboutHandler", aboutHandler).invoke(appInstance, proxy);
116 appClass.getDeclaredMethod("setOpenFileHandler", openFilesHandler).invoke(appInstance, proxy);
117 appClass.getDeclaredMethod("setPreferencesHandler", preferencesHandler).invoke(appInstance, proxy);
118 }
119
[12123]120 /**
121 * Find Apple handler class in {@code com.apple.eawt} or {@code java.awt.desktop} packages.
122 * @param className simple class name
123 * @return class
124 * @throws ClassNotFoundException if the handler class cannot be found
125 */
[10178]126 protected Class<?> findHandlerClass(String className) throws ClassNotFoundException {
127 try {
[12268]128 // Java 8 handlers
[10178]129 return Class.forName("com.apple.eawt."+className);
130 } catch (ClassNotFoundException e) {
[12620]131 Logging.trace(e);
[12268]132 // Java 9 handlers
[10178]133 return Class.forName("java.awt.desktop."+className);
134 }
135 }
136
[7482]137 /**
138 * Enables fullscreen support for the given window.
139 * @param window The window for which full screen will be available
140 * @since 7482
141 */
142 public static void enableOSXFullscreen(Window window) {
143 CheckParameterUtil.ensureParameterNotNull(window, "window");
144 try {
145 // http://stackoverflow.com/a/8693890/2257172
146 Class<?> eawtFullScreenUtilities = Class.forName("com.apple.eawt.FullScreenUtilities");
147 eawtFullScreenUtilities.getDeclaredMethod("setWindowCanFullScreen",
[12279]148 Window.class, boolean.class).invoke(eawtFullScreenUtilities, window, Boolean.TRUE);
[7482]149 } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException e) {
[12620]150 Logging.warn("Failed to register with OSX: " + e);
[7482]151 }
152 }
153
[12695]154 @Override
155 public void setNativeOsCallback(NativeOsCallback callback) {
156 osCallback = Objects.requireNonNull(callback);
157 }
158
[7253]159 @SuppressWarnings("unchecked")
[6084]160 @Override
[7253]161 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
[12620]162 if (Logging.isDebugEnabled()) {
163 Logging.debug("OSX handler: {0} - {1}", method.getName(), Arrays.toString(args));
[7283]164 }
[7012]165 switch (method.getName()) {
[7253]166 case "openFiles":
167 if (args[0] != null) {
168 try {
[7287]169 Object oFiles = args[0].getClass().getMethod("getFiles").invoke(args[0]);
[7253]170 if (oFiles instanceof List) {
[12695]171 osCallback.openFiles((List<File>) oFiles);
[7253]172 }
173 } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException ex) {
[12620]174 Logging.warn("Failed to access open files event: " + ex);
[7253]175 }
176 }
[7012]177 break;
[7287]178 case "handleQuitRequestWith":
[12695]179 boolean closed = osCallback.handleQuitRequest();
[7287]180 if (args[1] != null) {
[10178]181 try {
182 args[1].getClass().getDeclaredMethod(closed ? "performQuit" : "cancelQuit").invoke(args[1]);
183 } catch (IllegalAccessException e) {
[12620]184 Logging.debug(e);
[10178]185 // with Java 9, module java.desktop does not export com.apple.eawt, use new Desktop API instead
186 Class.forName("java.awt.desktop.QuitResponse").getMethod(closed ? "performQuit" : "cancelQuit").invoke(args[1]);
187 }
[7287]188 }
189 break;
[7012]190 case "handleAbout":
[12695]191 osCallback.handleAbout();
[7012]192 break;
193 case "handlePreferences":
[12695]194 osCallback.handlePreferences();
[7012]195 break;
196 default:
[12620]197 Logging.warn("OSX unsupported method: "+method.getName());
[7012]198 }
[1169]199 return null;
200 }
[6851]201
[1842]202 @Override
[1169]203 public void openUrl(String url) throws IOException {
204 Runtime.getRuntime().exec("open " + url);
205 }
[4897]206
[1842]207 @Override
[1169]208 public void initSystemShortcuts() {
[8510]209 // CHECKSTYLE.OFF: LineLength
[10339]210 auto(Shortcut.registerSystemShortcut("apple-reserved-01", tr("reserved"), KeyEvent.VK_SPACE, KeyEvent.META_DOWN_MASK)); // Show or hide the Spotlight search field (when multiple languages are installed, may rotate through enabled script systems).
211 auto(Shortcut.registerSystemShortcut("apple-reserved-02", tr("reserved"), KeyEvent.VK_SPACE, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Apple reserved.
212 auto(Shortcut.registerSystemShortcut("apple-reserved-03", tr("reserved"), KeyEvent.VK_SPACE, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Show the Spotlight search results window (when multiple languages are installed, may rotate through keyboard layouts and input methods within a script).
213 auto(Shortcut.registerSystemShortcut("apple-reserved-04", tr("reserved"), KeyEvent.VK_SPACE, KeyEvent.META_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); // | Apple reserved.
214 auto(Shortcut.registerSystemShortcut("apple-reserved-05", tr("reserved"), KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)); // Navigate through controls in a reverse direction. See "Keyboard Focus and Navigation."
215 auto(Shortcut.registerSystemShortcut("apple-reserved-06", tr("reserved"), KeyEvent.VK_TAB, KeyEvent.META_DOWN_MASK)); // Move forward to the next most recently used application in a list of open applications.
216 auto(Shortcut.registerSystemShortcut("apple-reserved-07", tr("reserved"), KeyEvent.VK_TAB, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Move backward through a list of open applications (sorted by recent use).
217 auto(Shortcut.registerSystemShortcut("apple-reserved-08", tr("reserved"), KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK)); // Move focus to the next grouping of controls in a dialog or the next table (when Tab moves to the next cell). See Accessibility Overview.
218 auto(Shortcut.registerSystemShortcut("apple-reserved-09", tr("reserved"), KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Move focus to the previous grouping of controls. See Accessibility Overview.
219 auto(Shortcut.registerSystemShortcut("apple-reserved-10", tr("reserved"), KeyEvent.VK_ESCAPE, KeyEvent.META_DOWN_MASK)); // Open Front Row.
220 auto(Shortcut.registerSystemShortcut("apple-reserved-11", tr("reserved"), KeyEvent.VK_ESCAPE, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Open the Force Quit dialog.
221 auto(Shortcut.registerSystemShortcut("apple-reserved-12", tr("reserved"), KeyEvent.VK_F1, KeyEvent.CTRL_DOWN_MASK)); // Toggle full keyboard access on or off. See Accessibility Overview.
222 auto(Shortcut.registerSystemShortcut("apple-reserved-13", tr("reserved"), KeyEvent.VK_F2, KeyEvent.CTRL_DOWN_MASK)); // Move focus to the menu bar. See Accessibility Overview.
223 auto(Shortcut.registerSystemShortcut("apple-reserved-14", tr("reserved"), KeyEvent.VK_F3, KeyEvent.CTRL_DOWN_MASK)); // Move focus to the Dock. See Accessibility Overview.
224 auto(Shortcut.registerSystemShortcut("apple-reserved-15", tr("reserved"), KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK)); // Move focus to the active (or next) window. See Accessibility Overview.
225 auto(Shortcut.registerSystemShortcut("apple-reserved-16", tr("reserved"), KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Move focus to the previously active window. See Accessibility Overview.
226 auto(Shortcut.registerSystemShortcut("apple-reserved-17", tr("reserved"), KeyEvent.VK_F5, KeyEvent.CTRL_DOWN_MASK)); // Move focus to the toolbar. See Accessibility Overview.
227 auto(Shortcut.registerSystemShortcut("apple-reserved-18", tr("reserved"), KeyEvent.VK_F5, KeyEvent.META_DOWN_MASK)); // Turn VoiceOver on or off. See Accessibility Overview.
228 auto(Shortcut.registerSystemShortcut("apple-reserved-19", tr("reserved"), KeyEvent.VK_F6, KeyEvent.CTRL_DOWN_MASK)); // Move focus to the first (or next) panel. See Accessibility Overview.
229 auto(Shortcut.registerSystemShortcut("apple-reserved-20", tr("reserved"), KeyEvent.VK_F6, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Move focus to the previous panel. See Accessibility Overview.
230 auto(Shortcut.registerSystemShortcut("apple-reserved-21", tr("reserved"), KeyEvent.VK_F7, KeyEvent.CTRL_DOWN_MASK)); // Temporarily override the current keyboard access mode in windows and dialogs. See Accessibility Overview.
231 //auto(Shortcut.registerSystemShortcut("apple-reserved-22", tr("reserved"), KeyEvent.VK_F9, 0)); // Tile or untile all open windows.
232 //auto(Shortcut.registerSystemShortcut("apple-reserved-23", tr("reserved"), KeyEvent.VK_F10, 0)); // Tile or untile all open windows in the currently active application.
233 //auto(Shortcut.registerSystemShortcut("apple-reserved-24", tr("reserved"), KeyEvent.VK_F11, 0)); // Hide or show all open windows.
234 //auto(Shortcut.registerSystemShortcut("apple-reserved-25", tr("reserved"), KeyEvent.VK_F12, 0)); // Hide or display Dashboard.
235 auto(Shortcut.registerSystemShortcut("apple-reserved-26", tr("reserved"), KeyEvent.VK_DEAD_GRAVE, KeyEvent.META_DOWN_MASK)); // Activate the next open window in the frontmost application. See "Window Layering."
236 auto(Shortcut.registerSystemShortcut("apple-reserved-27", tr("reserved"), KeyEvent.VK_DEAD_GRAVE, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Activate the previous open window in the frontmost application. See "Window Layering."
237 auto(Shortcut.registerSystemShortcut("apple-reserved-28", tr("reserved"), KeyEvent.VK_DEAD_GRAVE, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Move focus to the window drawer.
238 //auto(Shortcut.registerSystemShortcut("apple-reserved-29", tr("reserved"), KeyEvent.VK_MINUS, KeyEvent.META_DOWN_MASK)); // Decrease the size of the selected item (equivalent to the Smaller command). See "The Format Menu."
239 auto(Shortcut.registerSystemShortcut("apple-reserved-30", tr("reserved"), KeyEvent.VK_MINUS, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Zoom out when screen zooming is on. See Accessibility Overview.
[1023]240
[7605]241 //Shortcut.registerSystemShortcut("system:align-left", tr("reserved"), KeyEvent.VK_OPEN_BRACKET, KeyEvent.META_DOWN_MASK); // Left-align a selection (equivalent to the Align Left command). See "The Format Menu."
242 //Shortcut.registerSystemShortcut("system:align-right",tr("reserved"), KeyEvent.VK_CLOSE_BRACKET, KeyEvent.META_DOWN_MASK); // Right-align a selection (equivalent to the Align Right command). See "The Format Menu."
[1169]243 // I found no KeyEvent for |
[4995]244 //Shortcut.registerSystemCut("system:align-center", tr("reserved"), '|', KeyEvent.META_DOWN_MASK); // Center-align a selection (equivalent to the Align Center command). See "The Format Menu."
[7605]245 //Shortcut.registerSystemShortcut("system:spelling", tr("reserved"), KeyEvent.VK_COLON, KeyEvent.META_DOWN_MASK); // Display the Spelling window (equivalent to the Spelling command). See "The Edit Menu."
246 //Shortcut.registerSystemShortcut("system:spellcheck", tr("reserved"), KeyEvent.VK_SEMICOLON, KeyEvent.META_DOWN_MASK); // Find misspelled words in the document (equivalent to the Check Spelling command). See "The Edit Menu."
[10339]247 auto(Shortcut.registerSystemShortcut("system:preferences", tr("reserved"), KeyEvent.VK_COMMA, KeyEvent.META_DOWN_MASK)); // Open the application's preferences window (equivalent to the Preferences command). See "The Application Menu."
[1023]248
[10339]249 auto(Shortcut.registerSystemShortcut("apple-reserved-31", tr("reserved"), KeyEvent.VK_COMMA, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Decrease screen contrast. See Accessibility Overview.
250 auto(Shortcut.registerSystemShortcut("apple-reserved-32", tr("reserved"), KeyEvent.VK_PERIOD, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Increase screen contrast. See Accessibility Overview.
[1023]251
[1169]252 // I found no KeyEvent for ?
[10339]253 //auto(Shortcut.registerSystemCut("system:help", tr("reserved"), '?', KeyEvent.META_DOWN_MASK)); // Open the application's help in Help Viewer. See "The Help Menu."
[1023]254
[10339]255 auto(Shortcut.registerSystemShortcut("apple-reserved-33", tr("reserved"), KeyEvent.VK_SLASH, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Turn font smoothing on or off.
256 auto(Shortcut.registerSystemShortcut("apple-reserved-34", tr("reserved"), KeyEvent.VK_EQUALS, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Increase the size of the selected item (equivalent to the Bigger command). See "The Format Menu."
257 auto(Shortcut.registerSystemShortcut("apple-reserved-35", tr("reserved"), KeyEvent.VK_EQUALS, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Zoom in when screen zooming is on. See Accessibility Overview.
258 auto(Shortcut.registerSystemShortcut("apple-reserved-36", tr("reserved"), KeyEvent.VK_3, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Capture the screen to a file.
259 auto(Shortcut.registerSystemShortcut("apple-reserved-37", tr("reserved"), KeyEvent.VK_3, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); // Capture the screen to the Clipboard.
260 auto(Shortcut.registerSystemShortcut("apple-reserved-38", tr("reserved"), KeyEvent.VK_4, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Capture a selection to a file.
261 auto(Shortcut.registerSystemShortcut("apple-reserved-39", tr("reserved"), KeyEvent.VK_4, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); // Capture a selection to the Clipboard.
262 auto(Shortcut.registerSystemShortcut("apple-reserved-40", tr("reserved"), KeyEvent.VK_8, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Turn screen zooming on or off. See Accessibility Overview.
263 auto(Shortcut.registerSystemShortcut("apple-reserved-41", tr("reserved"), KeyEvent.VK_8, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); // Invert the screen colors. See Accessibility Overview.
[1023]264
[4995]265 Shortcut.registerSystemShortcut("system:selectall", tr("reserved"), KeyEvent.VK_A, KeyEvent.META_DOWN_MASK); // Highlight every item in a document or window, or all characters in a text field (equivalent to the Select All command). See "The Edit Menu."
[7605]266 //Shortcut.registerSystemShortcut("system:bold", tr("reserved"), KeyEvent.VK_B, KeyEvent.META_DOWN_MASK); // Boldface the selected text or toggle boldfaced text on and off (equivalent to the Bold command). See "The Edit Menu."
[4995]267 Shortcut.registerSystemShortcut("system:copy", tr("reserved"), KeyEvent.VK_C, KeyEvent.META_DOWN_MASK); // Duplicate the selected data and store on the Clipboard (equivalent to the Copy command). See "The Edit Menu."
[7605]268 //Shortcut.registerSystemShortcut("system:colors", tr("reserved"), KeyEvent.VK_C, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK); // Display the Colors window (equivalent to the Show Colors command). See "The Format Menu."
269 //Shortcut.registerSystemShortcut("system:copystyle", tr("reserved"), KeyEvent.VK_C, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Copy the style of the selected text (equivalent to the Copy Style command). See "The Format Menu."
[10339]270 //Shortcut.registerSystemShortcut("system:copyformat", tr("reserved"), KeyEvent.VK_C, KeyEvent.META_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); // Copy the formatting settings of the selected item and store on the Clipboard (equivalent to the Copy Ruler command). See "The Format Menu."
[1023]271
[10339]272 auto(Shortcut.registerSystemShortcut("apple-reserved-42", tr("reserved"), KeyEvent.VK_D, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Show or hide the Dock. See "The Dock."
[1023]273
[4995]274 Shortcut.registerSystemShortcut("system:dictionarylookup", tr("reserved"), KeyEvent.VK_D, KeyEvent.META_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK); // Display the definition of the selected word in the Dictionary application.
[7605]275 //Shortcut.registerSystemShortcut("system:findselected", tr("reserved"), KeyEvent.VK_E, KeyEvent.META_DOWN_MASK); // Use the selection for a find operation. See "Find Windows."
[4995]276 Shortcut.registerSystemShortcut("system:find", tr("reserved"), KeyEvent.VK_F, KeyEvent.META_DOWN_MASK); // Open a Find window (equivalent to the Find command). See "The Edit Menu."
277 Shortcut.registerSystemShortcut("system:search", tr("reserved"), KeyEvent.VK_F, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Jump to the search field control. See "Search Fields."
[7605]278 //Shortcut.registerSystemShortcut("system:findnext", tr("reserved"), KeyEvent.VK_G, KeyEvent.META_DOWN_MASK); // Find the next occurrence of the selection (equivalent to the Find Next command). See "The Edit Menu."
279 //Shortcut.registerSystemShortcut("system:findprev", tr("reserved"), KeyEvent.VK_G, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK); // Find the previous occurrence of the selection (equivalent to the Find Previous command). See "The Edit Menu."
[10339]280 auto(Shortcut.registerSystemShortcut("system:hide", tr("reserved"), KeyEvent.VK_H, KeyEvent.META_DOWN_MASK)); // Hide the windows of the currently running application (equivalent to the Hide ApplicationName command). See "The Application Menu."
281 auto(Shortcut.registerSystemShortcut("system:hideothers", tr("reserved"), KeyEvent.VK_H, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Hide the windows of all other running applications (equivalent to the Hide Others command). See "The Application Menu."
[1169]282 // What about applications that have italic text AND info windows?
[4995]283 //Shortcut.registerSystemCut("system:italic", tr("reserved"), KeyEvent.VK_I, KeyEvent.META_DOWN_MASK); // Italicize the selected text or toggle italic text on or off (equivalent to the Italic command). See "The Format Menu."
[7605]284 //Shortcut.registerSystemShortcut("system:info", tr("reserved"), KeyEvent.VK_I, KeyEvent.META_DOWN_MASK); // Display an Info window. See "Inspector Windows."
285 //Shortcut.registerSystemShortcut("system:inspector", tr("reserved"), KeyEvent.VK_I, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Display an inspector window. See "Inspector Windows."
286 //Shortcut.registerSystemShortcut("system:toselection", tr("reserved"), KeyEvent.VK_J, KeyEvent.META_DOWN_MASK); // Scroll to a selection.
287 //Shortcut.registerSystemShortcut("system:minimize", tr("reserved"), KeyEvent.VK_M, KeyEvent.META_DOWN_MASK); // Minimize the active window to the Dock (equivalent to the Minimize command). See "The Window Menu."
288 //Shortcut.registerSystemShortcut("system:minimizeall", tr("reserved"), KeyEvent.VK_M, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Minimize all windows of the active application to the Dock (equivalent to the Minimize All command). See "The Window Menu."
[4995]289 Shortcut.registerSystemShortcut("system:new", tr("reserved"), KeyEvent.VK_N, KeyEvent.META_DOWN_MASK); // Open a new document (equivalent to the New command). See "The File Menu."
290 Shortcut.registerSystemShortcut("system:open", tr("reserved"), KeyEvent.VK_O, KeyEvent.META_DOWN_MASK); // Display a dialog for choosing a document to open (equivalent to the Open command). See "The File Menu."
291 Shortcut.registerSystemShortcut("system:print", tr("reserved"), KeyEvent.VK_P, KeyEvent.META_DOWN_MASK); // Display the Print dialog (equivalent to the Print command). See "The File Menu."
[7605]292 //Shortcut.registerSystemShortcut("system:printsetup", tr("reserved"), KeyEvent.VK_P, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK); // Display a dialog for specifying printing parameters (equivalent to the Page Setup command). See "The File Menu."
[10339]293 auto(Shortcut.registerSystemShortcut("system:menuexit", tr("reserved"), KeyEvent.VK_Q, KeyEvent.META_DOWN_MASK)); // Quit the application (equivalent to the Quit command). See "The Application Menu."
[1023]294
[10339]295 auto(Shortcut.registerSystemShortcut("apple-reserved-43", tr("reserved"), KeyEvent.VK_Q, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Log out the current user (equivalent to the Log Out command).
296 auto(Shortcut.registerSystemShortcut("apple-reserved-44", tr("reserved"), KeyEvent.VK_Q, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)); // Log out the current user without confirmation.
[1023]297
[4995]298 Shortcut.registerSystemShortcut("system:save", tr("reserved"), KeyEvent.VK_S, KeyEvent.META_DOWN_MASK); // Save the active document (equivalent to the Save command). See "The File Menu."
299 Shortcut.registerSystemShortcut("system:saveas", tr("reserved"), KeyEvent.VK_S, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK); // Display the Save dialog (equivalent to the Save As command). See "The File Menu."
[7605]300 //Shortcut.registerSystemShortcut("system:fonts", tr("reserved"), KeyEvent.VK_T, KeyEvent.META_DOWN_MASK); // Display the Fonts window (equivalent to the Show Fonts command). See "The Format Menu."
[4995]301 Shortcut.registerSystemShortcut("system:toggletoolbar", tr("reserved"), KeyEvent.VK_T, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Show or hide a toolbar (equivalent to the Show/Hide Toolbar command). See "The View Menu" and "Toolbars."
[7605]302 //Shortcut.registerSystemShortcut("system:underline", tr("reserved"), KeyEvent.VK_U, KeyEvent.META_DOWN_MASK); // Underline the selected text or turn underlining on or off (equivalent to the Underline command). See "The Format Menu."
[4995]303 Shortcut.registerSystemShortcut("system:paste", tr("reserved"), KeyEvent.VK_V, KeyEvent.META_DOWN_MASK); // Insert the Clipboard contents at the insertion point (equivalent to the Paste command). See "The File Menu."
[7605]304 //Shortcut.registerSystemShortcut("system:pastestyle", tr("reserved"), KeyEvent.VK_V, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Apply the style of one object to the selected object (equivalent to the Paste Style command). See "The Format Menu."
305 //Shortcut.registerSystemShortcut("system:pastemwithoutstyle", tr("reserved"), KeyEvent.VK_V, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Apply the style of the surrounding text to the inserted object (equivalent to the Paste and Match Style command). See "The Edit Menu."
306 //Shortcut.registerSystemShortcut("system:pasteformatting", tr("reserved"), KeyEvent.VK_V, KeyEvent.META_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK); // Apply formatting settings to the selected object (equivalent to the Paste Ruler command). See "The Format Menu."
307 //Shortcut.registerSystemShortcut("system:closewindow", tr("reserved"), KeyEvent.VK_W, KeyEvent.META_DOWN_MASK); // Close the active window (equivalent to the Close command). See "The File Menu."
[4995]308 Shortcut.registerSystemShortcut("system:closefile", tr("reserved"), KeyEvent.VK_W, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK); // Close a file and its associated windows (equivalent to the Close File command). See "The File Menu."
309 Shortcut.registerSystemShortcut("system:closeallwindows", tr("reserved"), KeyEvent.VK_W, KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK); // Close all windows in the application (equivalent to the Close All command). See "The File Menu."
310 Shortcut.registerSystemShortcut("system:cut", tr("reserved"), KeyEvent.VK_X, KeyEvent.META_DOWN_MASK); // Remove the selection and store on the Clipboard (equivalent to the Cut command). See "The Edit Menu."
311 Shortcut.registerSystemShortcut("system:undo", tr("reserved"), KeyEvent.VK_Z, KeyEvent.META_DOWN_MASK); // Reverse the effect of the user's previous operation (equivalent to the Undo command). See "The Edit Menu."
312 Shortcut.registerSystemShortcut("system:redo", tr("reserved"), KeyEvent.VK_Z, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK); // Reverse the effect of the last Undo command (equivalent to the Redo command). See "The Edit Menu."
[1023]313
[10339]314 auto(Shortcut.registerSystemShortcut("apple-reserved-45", tr("reserved"), KeyEvent.VK_RIGHT, KeyEvent.META_DOWN_MASK)); // Change the keyboard layout to current layout of Roman script.
315 //auto(Shortcut.registerSystemCut("apple-reserved-46", tr("reserved"), KeyEvent.VK_RIGHT, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the next semantic unit, typically the end of the current line.
316 //auto(Shortcut.registerSystemCut("apple-reserved-47", tr("reserved"), KeyEvent.VK_RIGHT, KeyEvent.SHIFT_DOWN_MASK)); // Extend selection one character to the right.
317 //auto(Shortcut.registerSystemCut("apple-reserved-48", tr("reserved"), KeyEvent.VK_RIGHT, KeyEvent.ALT_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the end of the current word, then to the end of the next word.
[1023]318
[4995]319 Shortcut.registerSystemShortcut("system:movefocusright", tr("reserved"), KeyEvent.VK_RIGHT, KeyEvent.CTRL_DOWN_MASK); // Move focus to another value or cell within a view, such as a table. See Accessibility Overview.
[1023]320
[10339]321 auto(Shortcut.registerSystemShortcut("apple-reserved-49", tr("reserved"), KeyEvent.VK_LEFT, KeyEvent.META_DOWN_MASK)); // Change the keyboard layout to current layout of system script.
322 //auto(Shortcut.registerSystemCut("apple-reserved-50", tr("reserved"), KeyEvent.VK_LEFT, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the previous semantic unit, typically the beginning of the current line.
323 //auto(Shortcut.registerSystemCut("apple-reserved-51", tr("reserved"), KeyEvent.VK_LEFT, KeyEvent.SHIFT_DOWN_MASK)); // Extend selection one character to the left.
324 //auto(Shortcut.registerSystemCut("apple-reserved-52", tr("reserved"), KeyEvent.VK_LEFT, KeyEvent.ALT_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the beginning of the current word, then to the beginning of the previous word.
[1023]325
[4995]326 Shortcut.registerSystemShortcut("system:movefocusleft", tr("reserved"), KeyEvent.VK_LEFT, KeyEvent.CTRL_DOWN_MASK); // Move focus to another value or cell within a view, such as a table. See Accessibility Overview.
[1023]327
[10339]328 //auto(Shortcut.registerSystemCut("apple-reserved-53", tr("reserved"), KeyEvent.VK_UP, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection upward in the next semantic unit, typically the beginning of the document.
329 //auto(Shortcut.registerSystemCut("apple-reserved-54", tr("reserved"), KeyEvent.VK_UP, KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the line above, to the nearest character boundary at the same horizontal location.
330 //auto(Shortcut.registerSystemCut("apple-reserved-55", tr("reserved"), KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the beginning of the current paragraph, then to the beginning of the next paragraph.
[1023]331
[4995]332 Shortcut.registerSystemShortcut("system:movefocusup", tr("reserved"), KeyEvent.VK_UP, KeyEvent.CTRL_DOWN_MASK); // Move focus to another value or cell within a view, such as a table. See Accessibility Overview.
[1023]333
[10339]334 //auto(Shortcut.registerSystemCut("apple-reserved-56", tr("reserved"), KeyEvent.VK_DOWN, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection downward in the next semantic unit, typically the end of the document.
335 //auto(Shortcut.registerSystemCut("apple-reserved-57", tr("reserved"), KeyEvent.VK_DOWN, KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the line below, to the nearest character boundary at the same horizontal location.
336 //auto(Shortcut.registerSystemCut("apple-reserved-58", tr("reserved"), KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)); // Extend selection to the end of the current paragraph, then to the end of the next paragraph (include the blank line between paragraphs in cut, copy, and paste operations).
[1023]337
[4995]338 Shortcut.registerSystemShortcut("system:movefocusdown", tr("reserved"), KeyEvent.VK_DOWN, KeyEvent.CTRL_DOWN_MASK); // Move focus to another value or cell within a view, such as a table. See Accessibility Overview.
[1023]339
[10339]340 auto(Shortcut.registerSystemShortcut("system:about", tr("reserved"), 0, -1)); // About
[1643]341
[4995]342 Shortcut.registerSystemShortcut("view:zoomin", tr("reserved"), KeyEvent.VK_ADD, KeyEvent.META_DOWN_MASK); // Zoom in
343 Shortcut.registerSystemShortcut("view:zoomout", tr("reserved"), KeyEvent.VK_SUBTRACT, KeyEvent.META_DOWN_MASK); // Zoom out
[8510]344 // CHECKSTYLE.ON: LineLength
[1169]345 }
[6851]346
[10339]347 private static void auto(Shortcut sc) {
348 if (sc != null) {
349 sc.setAutomatic();
350 }
351 }
352
[1842]353 @Override
[1169]354 public String makeTooltip(String name, Shortcut sc) {
355 String lafid = UIManager.getLookAndFeel().getID();
356 boolean canHtml = true;
357 // "Mac" is the native LAF, "Aqua" is Quaqua. Both use native menus with native tooltips.
358 if (lafid.contains("Mac") || lafid.contains("Aqua")) {
359 canHtml = false;
360 }
[10242]361 StringBuilder result = new StringBuilder(48);
[1842]362 if (canHtml) {
[8848]363 result.append("<html>");
[1842]364 }
[8848]365 result.append(name);
[8461]366 if (sc != null && !sc.getKeyText().isEmpty()) {
[8848]367 result.append(' ');
[1842]368 if (canHtml) {
[8848]369 result.append("<font size='-2'>");
[1842]370 }
[8848]371 result.append('(').append(sc.getKeyText()).append(')');
[1842]372 if (canHtml) {
[8848]373 result.append("</font>");
[1842]374 }
[1169]375 }
[1842]376 if (canHtml) {
[8848]377 result.append("&nbsp;</html>");
[1842]378 }
[8848]379 return result.toString();
[1169]380 }
[2371]381
382 @Override
[6443]383 public String getDefaultStyle() {
[7480]384 return "com.apple.laf.AquaLookAndFeel";
[2371]385 }
[4153]386
387 @Override
[6443]388 public boolean canFullscreen() {
[7482]389 // OS X provides native full screen support registered at initialization, no need for custom action
[4203]390 return false;
391 }
[6070]392
[5850]393 @Override
394 public String getOSDescription() {
[8846]395 return System.getProperty("os.name") + ' ' + System.getProperty("os.version");
[5850]396 }
[7829]397
[12217]398 private String buildOSBuildNumber() {
399 StringBuilder sb = new StringBuilder();
400 try {
401 sb.append(exec("sw_vers", "-productName"))
402 .append(' ')
403 .append(exec("sw_vers", "-productVersion"))
404 .append(" (")
405 .append(exec("sw_vers", "-buildVersion"))
406 .append(')');
407 } catch (IOException e) {
[12620]408 Logging.error(e);
[12217]409 }
410 return sb.toString();
411 }
412
[7829]413 @Override
[12217]414 public String getOSBuildNumber() {
415 if (oSBuildNumber == null) {
416 oSBuildNumber = buildOSBuildNumber();
417 }
418 return oSBuildNumber;
419 }
420
421 @Override
[7829]422 public File getDefaultCacheDirectory() {
[11162]423 return new File(System.getProperty("user.home")+"/Library/Caches",
424 Main.pref.getJOSMDirectoryBaseName());
[7829]425 }
[7831]426
427 @Override
428 public File getDefaultPrefDirectory() {
[11162]429 return new File(System.getProperty("user.home")+"/Library/Preferences",
430 Main.pref.getJOSMDirectoryBaseName());
[7831]431 }
[7834]432
[7846]433 @Override
[7834]434 public File getDefaultUserDataDirectory() {
[11162]435 return new File(System.getProperty("user.home")+"/Library",
436 Main.pref.getJOSMDirectoryBaseName());
[7834]437 }
[13450]438
439 @Override
440 public X509Certificate getX509Certificate(NativeCertAmend certAmend)
441 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
442 try {
443 // Get platform certificate in PEM format
444 String pem = Utils.execOutput(Arrays.asList("security", "find-certificate",
445 "-c", certAmend.getMacAlias(), "-p", "/System/Library/Keychains/SystemRootCertificates.keychain"));
446 Logging.debug(pem);
447 return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(
448 new ByteArrayInputStream(pem.getBytes(StandardCharsets.UTF_8)));
449 } catch (ExecutionException | InterruptedException | IllegalArgumentException e) {
450 throw new IOException(e);
451 }
452 }
[2371]453}
Note: See TracBrowser for help on using the repository browser.