Browse Source

fix: update shell.openExternal to correctly focus on external window (#44469)

* Revert "docs: fix `win.getContentView(`) return type (#44464)"

This reverts commit b11c6cf9bf494beb31268091bf250a3da7c3faf1.

* fix: Use openURL:configuration:completionHandler instead of openUrl

Co-authored-by: alice <[email protected]>

* test: add a test

Co-authored-by: alice <[email protected]>

* fix: add dispatch_async to replace GetUIThreadTaskRunner

Co-authored-by: alice <[email protected]>

* refactor: remove unused import

Co-authored-by: alice <[email protected]>

* fix: update to use BindPostTaskToCurrentDefault

Co-authored-by: alice <[email protected]>

* test: add regression test for window focus

Co-authored-by: alice <[email protected]>

* refactor: update to explicit task runner

Co-authored-by: alice <[email protected]>

---------

Co-authored-by: Charles Kerr <[email protected]>
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: alice <[email protected]>
trop[bot] 5 months ago
parent
commit
5d5c18b7a6
3 changed files with 37 additions and 5 deletions
  1. 1 1
      docs/api/base-window.md
  2. 21 4
      shell/common/platform_util_mac.mm
  3. 15 0
      spec/api-shell-spec.ts

+ 1 - 1
docs/api/base-window.md

@@ -512,7 +512,7 @@ Sets the content view of the window.
 
 #### `win.getContentView()`
 
-Returns [`View`](view.md) - The content view of the window.
+Returns [View](view.md) - The content view of the window.
 
 #### `win.destroy()`
 

+ 21 - 4
shell/common/platform_util_mac.mm

@@ -19,6 +19,7 @@
 #include "base/logging.h"
 #include "base/mac/scoped_aedesc.h"
 #include "base/strings/sys_string_conversions.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/task/thread_pool.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "electron/mas.h"
@@ -147,11 +148,27 @@ void OpenExternal(const GURL& url,
     return;
   }
 
-  bool success = [[NSWorkspace sharedWorkspace] openURL:ns_url];
-  if (success && options.activate)
-    [NSApp activateIgnoringOtherApps:YES];
+  NSWorkspaceOpenConfiguration* configuration =
+      [NSWorkspaceOpenConfiguration configuration];
+  configuration.activates = options.activate;
+
+  __block OpenCallback copied_callback = std::move(callback);
+  scoped_refptr<base::SequencedTaskRunner> runner =
+      base::SequencedTaskRunner::GetCurrentDefault();
 
-  std::move(callback).Run(success ? "" : "Failed to open URL");
+  [[NSWorkspace sharedWorkspace]
+                openURL:ns_url
+          configuration:configuration
+      completionHandler:^(NSRunningApplication* _Nullable app,
+                          NSError* _Nullable error) {
+        if (error) {
+          runner->PostTask(FROM_HERE, base::BindOnce(std::move(copied_callback),
+                                                     "Failed to open URL"));
+        } else {
+          runner->PostTask(FROM_HERE,
+                           base::BindOnce(std::move(copied_callback), ""));
+        }
+      }];
 }
 
 bool MoveItemToTrashWithError(const base::FilePath& full_path,

+ 15 - 0
spec/api-shell-spec.ts

@@ -76,6 +76,21 @@ describe('shell module', () => {
         requestReceived
       ]);
     });
+
+    ifit(process.platform === 'darwin')('removes focus from the electron window after opening an external link', async () => {
+      const url = 'http://127.0.0.1';
+      const w = new BrowserWindow({ show: true });
+
+      await once(w, 'focus');
+      expect(w.isFocused()).to.be.true();
+
+      await Promise.all<void>([
+        shell.openExternal(url),
+        once(w, 'blur') as Promise<any>
+      ]);
+
+      expect(w.isFocused()).to.be.false();
+    });
   });
 
   describe('shell.trashItem()', () => {