Browse Source

Support explicit cancelId on macOS

Kevin Sawicki 8 years ago
parent
commit
be16e75be2
2 changed files with 15 additions and 6 deletions
  1. 13 4
      atom/browser/ui/message_box_mac.mm
  2. 2 2
      docs/api/dialog.md

+ 13 - 4
atom/browser/ui/message_box_mac.mm

@@ -57,6 +57,7 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
                        MessageBoxType type,
                        const std::vector<std::string>& buttons,
                        int default_id,
+                       int cancel_id,
                        const std::string& title,
                        const std::string& message,
                        const std::string& detail,
@@ -89,7 +90,14 @@ NSAlert* CreateNSAlert(NativeWindow* parent_window,
   }
 
   NSArray* ns_buttons = [alert buttons];
-  if (default_id >= 0 && default_id < static_cast<int>([ns_buttons count])) {
+  int button_count = static_cast<int>([ns_buttons count]);
+
+  // Bind cancel id button to escape key if there is more than one button
+  if (button_count > 1 && cancel_id >= 0 && cancel_id < button_count) {
+    [[ns_buttons objectAtIndex:cancel_id] setKeyEquivalent:@"\e"];
+  }
+
+  if (default_id >= 0 && default_id < button_count) {
     // Focus the button at default_id if the user opted to do so.
     // The first button added gets set as the default selected.
     // So remove that default, and make the requested button the default.
@@ -129,7 +137,8 @@ int ShowMessageBox(NativeWindow* parent_window,
                    const std::string& detail,
                    const gfx::ImageSkia& icon) {
   NSAlert* alert = CreateNSAlert(parent_window, type, buttons, default_id,
-                                 title, message, detail, "", false, icon);
+                                 cancel_id, title, message, detail, "", false,
+                                 icon);
 
   // Use runModal for synchronous alert without parent, since we don't have a
   // window to wait for.
@@ -166,8 +175,8 @@ void ShowMessageBox(NativeWindow* parent_window,
                     const gfx::ImageSkia& icon,
                     const MessageBoxCallback& callback) {
   NSAlert* alert =
-      CreateNSAlert(parent_window, type, buttons, default_id, title, message,
-                    detail, checkbox_label, checkbox_checked, icon);
+      CreateNSAlert(parent_window, type, buttons, default_id, cancel_id, title,
+                    message, detail, checkbox_label, checkbox_checked, icon);
   ModalDelegate* delegate = [[ModalDelegate alloc] initWithCallback:callback
                                                            andAlert:alert
                                                        callEndModal:false];

+ 2 - 2
docs/api/dialog.md

@@ -141,8 +141,8 @@ will be passed via `callback(filename)`
   * `cancelId` Integer (optional) - The value will be returned when user cancels the dialog
     instead of clicking the buttons of the dialog. By default it is the index
     of the buttons that have "cancel" or "no" as label, or 0 if there is no such
-    buttons. On macOS and Windows the index of the "Cancel" button will always
-    be used as `cancelId` even if it is specified.
+    buttons. On Windows the index of the "Cancel" button will always be used
+    as `cancelId` even if it is specified.
   * `noLink` Boolean (optional) - On Windows Electron will try to figure out which one of
     the `buttons` are common buttons (like "Cancel" or "Yes"), and show the
     others as command links in the dialog. This can make the dialog appear in